home *** CD-ROM | disk | FTP | other *** search
/ CrystalVision Software Se… Wiki Wonder - Wikipedia / CrystalVision Software Services 703: The Wiki Wonder - Wikipedia.iso / 0703 / Educate / Complete Calc / Setup.exe / main.tcl < prev   
Encoding:
Text File  |  2006-12-28  |  536.7 KB  |  15,982 lines

  1. ## $Id$
  2. ##
  3. ## Copyright (C) 2002  Damon Courtney
  4. ## 
  5. ## This program is free software; you can redistribute it and/or
  6. ## modify it under the terms of the GNU General Public License
  7. ## as published by the Free Software Foundation; either version 2
  8. ## of the License, or (at your option) any later version.
  9. ## 
  10. ## This program is distributed in the hope that it will be useful,
  11. ## but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. ## GNU General Public License for more details.
  14. ## 
  15. ## You should have received a copy of the GNU General Public License
  16. ## along with this program; if not, write to the
  17. ##     Free Software Foundation, Inc.
  18. ##     51 Franklin Street, Fifth Floor
  19. ##     Boston, MA  02110-1301, USA.
  20. ##
  21.  
  22. if {[info exists ::InstallJammer]} { return }
  23.  
  24. catch { wm withdraw . }
  25.  
  26. namespace eval ::InstallJammer {}
  27.  
  28. trace add variable ::info write ::InstallJammer::AdjustBooleanVars
  29.  
  30. proc ::InstallJammer::AdjustBooleanVars { name1 name2 op } {
  31.     ## If a user is typing into an entry that has a -textvariable
  32.     ## in the info array, we don't want to adjust what the user is typing.
  33.     if {![catch { lindex [info level -1] 0 } cmd]} {
  34.         if {$cmd eq "tk::EntryInsert" || $cmd eq "tile::entry::Insert"} {
  35.             return
  36.         }
  37.     }
  38.  
  39.     if {[string length $name2]} {
  40.         upvar #0 ${name1}($name2) var
  41.     } else {
  42.         upvar #0 $name1 var
  43.     }
  44.  
  45.     if {[info exists var]} {
  46.         if {[string is true -strict $var]} {
  47.             set var 1
  48.         } elseif {[string is false -strict $var]} {
  49.             set var 0
  50.         }
  51.     }
  52. }
  53.  
  54. namespace eval ::InstallJammer {}
  55. namespace eval ::InstallAPI {}
  56. set conf(version)     1.0.4
  57. set info(Platform)    Windows
  58. set info(InstallerID) A7CE50BB-3922-4F13-9F73-D0CABA617F3E
  59. array set ::InstallJammer::languagecodes {de    "German"
  60. en    "English"
  61. es    "Spanish"
  62. fr    "French"
  63. it    "Italian"
  64. pt_br "Brazilian Portugese"
  65. }
  66. array set info {
  67. AllowLanguageSelection
  68. No
  69.  
  70. AppName
  71. CompleteCalc
  72.  
  73. ApplicationID
  74. 5923DED3-7B26-46DF-BDA9-724CB75A4A1E
  75.  
  76. ApplicationURL
  77. {}
  78.  
  79. BuildType
  80. {}
  81.  
  82. BuildVersion
  83. 0
  84.  
  85. CancelledInstallAction
  86. {Rollback and Stop}
  87.  
  88. CleanupCancelledInstall
  89. Yes
  90.  
  91. Company
  92. {Check n Do}
  93.  
  94. CreateDesktopShortcut
  95. Yes
  96.  
  97. CreateQuickLaunchShortcut
  98. Yes
  99.  
  100. DefaultLanguage
  101. English
  102.  
  103. IncludeDebugging
  104. Yes
  105.  
  106. InstallDir
  107. <%PROGRAM_FILES%>/<%AppName%>
  108.  
  109. InstallType
  110. Typical
  111.  
  112. InstallVersion
  113. 1.2.1.0
  114.  
  115. LaunchApplication
  116. Yes
  117.  
  118. MajorVersion
  119. 1
  120.  
  121. MinorVersion
  122. 2
  123.  
  124. PatchVersion
  125. 1
  126.  
  127. ProgramExecutable
  128. <%InstallDir%>/CompleteCalc.exe
  129.  
  130. ProgramFolderAllUsers
  131. No
  132.  
  133. ProgramFolderName
  134. <%AppName%>
  135.  
  136. ProgramLicense
  137. <%InstallDir%>/LICENSE.txt
  138.  
  139. ProgramName
  140. {}
  141.  
  142. ProgramReadme
  143. <%InstallDir%>/README.txt
  144.  
  145. ShortAppName
  146. CompleteCalc
  147.  
  148. Version
  149. 1.2.1
  150.  
  151. ViewReadme
  152. Yes
  153.  
  154. }
  155. set info(WindowsSpecialDirs) {ALTSTARTUP APPDATA BITBUCKET COMMON_ALTSTARTUP COMMON_DESKTOPDIRECTORY COMMON_FAVORITES COMMON_PROGRAMS COMMON_STARTMENU COMMON_STARTUP CONTROLS COOKIES DESKTOP DESKTOPDIRECTORY DRIVES FAVORITES FONTS HISTORY INTERNET INTERNET_CACHE NETHOOD NETWORK PERSONAL PRINTERS PRINTHOOD PROGRAMS PROGRAM_FILES QUICK_LAUNCH RECENT SENDTO STARTMENU STARTUP SYSTEM SYSTEM32 TEMPLATES WINDOWS}
  156. array set ::InstallJammer::Properties {
  157. 00751641-DBBA-47C1-A7B9-0975B0C2644F,Active
  158. Yes
  159.  
  160. 00751641-DBBA-47C1-A7B9-0975B0C2644F,Alias
  161. {}
  162.  
  163. 00751641-DBBA-47C1-A7B9-0975B0C2644F,CheckCondition
  164. {Before Pane is Displayed}
  165.  
  166. 00751641-DBBA-47C1-A7B9-0975B0C2644F,Comment
  167. {}
  168.  
  169. 00751641-DBBA-47C1-A7B9-0975B0C2644F,Component
  170. {}
  171.  
  172. 00751641-DBBA-47C1-A7B9-0975B0C2644F,FailureMessage
  173. {}
  174.  
  175. 00751641-DBBA-47C1-A7B9-0975B0C2644F,ID
  176. {}
  177.  
  178. 00751641-DBBA-47C1-A7B9-0975B0C2644F,Operator
  179. false
  180.  
  181. 00751641-DBBA-47C1-A7B9-0975B0C2644F,String
  182. <%InstallStopped%>
  183.  
  184. 0509031B-2E3F-4330-B44F-1E1586B0B38F,Active
  185. Yes
  186.  
  187. 0509031B-2E3F-4330-B44F-1E1586B0B38F,Alias
  188. {}
  189.  
  190. 0509031B-2E3F-4330-B44F-1E1586B0B38F,CheckCondition
  191. {Before Pane is Displayed}
  192.  
  193. 0509031B-2E3F-4330-B44F-1E1586B0B38F,Comment
  194. {}
  195.  
  196. 0509031B-2E3F-4330-B44F-1E1586B0B38F,Component
  197. {}
  198.  
  199. 0509031B-2E3F-4330-B44F-1E1586B0B38F,FailureMessage
  200. {}
  201.  
  202. 0509031B-2E3F-4330-B44F-1E1586B0B38F,ID
  203. {}
  204.  
  205. 0509031B-2E3F-4330-B44F-1E1586B0B38F,Script
  206. {[<%CurrentPane%> get UserMustAcceptLicense]}
  207.  
  208. 0ACE12C8-A333-46A4-B24F-7C895219F2B0,Active
  209. Yes
  210.  
  211. 0ACE12C8-A333-46A4-B24F-7C895219F2B0,Alias
  212. {}
  213.  
  214. 0ACE12C8-A333-46A4-B24F-7C895219F2B0,CheckCondition
  215. {Before Pane is Displayed}
  216.  
  217. 0ACE12C8-A333-46A4-B24F-7C895219F2B0,Comment
  218. {}
  219.  
  220. 0ACE12C8-A333-46A4-B24F-7C895219F2B0,Component
  221. {}
  222.  
  223. 0ACE12C8-A333-46A4-B24F-7C895219F2B0,FailureMessage
  224. {}
  225.  
  226. 0ACE12C8-A333-46A4-B24F-7C895219F2B0,ID
  227. {}
  228.  
  229. 0ACE12C8-A333-46A4-B24F-7C895219F2B0,Operator
  230. false
  231.  
  232. 0ACE12C8-A333-46A4-B24F-7C895219F2B0,String
  233. <%InstallStopped%>
  234.  
  235. 1A5BA78D-0B6B-4051-B460-B94426C061F7,Active
  236. Yes
  237.  
  238. 1A5BA78D-0B6B-4051-B460-B94426C061F7,Alias
  239. {}
  240.  
  241. 1A5BA78D-0B6B-4051-B460-B94426C061F7,CommandLineArguments
  242. {}
  243.  
  244. 1A5BA78D-0B6B-4051-B460-B94426C061F7,Comment
  245. {}
  246.  
  247. 1A5BA78D-0B6B-4051-B460-B94426C061F7,Component
  248. {}
  249.  
  250. 1A5BA78D-0B6B-4051-B460-B94426C061F7,Conditions
  251. {}
  252.  
  253. 1A5BA78D-0B6B-4051-B460-B94426C061F7,ExecuteAction
  254. {After Pane is Displayed}
  255.  
  256. 1A5BA78D-0B6B-4051-B460-B94426C061F7,ID
  257. {}
  258.  
  259. 1A5BA78D-0B6B-4051-B460-B94426C061F7,IconPath
  260. {}
  261.  
  262. 1A5BA78D-0B6B-4051-B460-B94426C061F7,IconPathIndex
  263. 0
  264.  
  265. 1A5BA78D-0B6B-4051-B460-B94426C061F7,IgnoreErrors
  266. No
  267.  
  268. 1A5BA78D-0B6B-4051-B460-B94426C061F7,ShortcutDirectory
  269. <%QUICK_LAUNCH%>
  270.  
  271. 1A5BA78D-0B6B-4051-B460-B94426C061F7,ShortcutName
  272. <%AppName%>
  273.  
  274. 1A5BA78D-0B6B-4051-B460-B94426C061F7,TargetFileName
  275. <%ProgramExecutable%>
  276.  
  277. 1A5BA78D-0B6B-4051-B460-B94426C061F7,WindowState
  278. normal
  279.  
  280. 1A5BA78D-0B6B-4051-B460-B94426C061F7,WorkingDirectory
  281. <%InstallDir%>
  282.  
  283. 1AF0EAD8-E770-4022-849F-D4C625BE1284,Active
  284. Yes
  285.  
  286. 1AF0EAD8-E770-4022-849F-D4C625BE1284,Alias
  287. {Cancel Actions}
  288.  
  289. 1AF0EAD8-E770-4022-849F-D4C625BE1284,Comment
  290. {}
  291.  
  292. 1AF0EAD8-E770-4022-849F-D4C625BE1284,Conditions
  293. {}
  294.  
  295. 1AF0EAD8-E770-4022-849F-D4C625BE1284,ID
  296. {}
  297.  
  298. 1D8EB93F-5852-46CE-B93A-A4ED5672E32F,Action
  299. {Install Actions}
  300.  
  301. 1D8EB93F-5852-46CE-B93A-A4ED5672E32F,Active
  302. Yes
  303.  
  304. 1D8EB93F-5852-46CE-B93A-A4ED5672E32F,Alias
  305. {}
  306.  
  307. 1D8EB93F-5852-46CE-B93A-A4ED5672E32F,Comment
  308. {}
  309.  
  310. 1D8EB93F-5852-46CE-B93A-A4ED5672E32F,Component
  311. {}
  312.  
  313. 1D8EB93F-5852-46CE-B93A-A4ED5672E32F,Conditions
  314. {}
  315.  
  316. 1D8EB93F-5852-46CE-B93A-A4ED5672E32F,EvaluateConditions
  317. Yes
  318.  
  319. 1D8EB93F-5852-46CE-B93A-A4ED5672E32F,ExecuteAction
  320. {After Pane is Displayed}
  321.  
  322. 1D8EB93F-5852-46CE-B93A-A4ED5672E32F,ID
  323. {}
  324.  
  325. 1D8EB93F-5852-46CE-B93A-A4ED5672E32F,IgnoreErrors
  326. No
  327.  
  328. 211BD58E-6D44-49A5-AC4F-2DFA63C61083,Active
  329. Yes
  330.  
  331. 211BD58E-6D44-49A5-AC4F-2DFA63C61083,Alias
  332. {}
  333.  
  334. 211BD58E-6D44-49A5-AC4F-2DFA63C61083,CheckCondition
  335. {Before Pane is Displayed}
  336.  
  337. 211BD58E-6D44-49A5-AC4F-2DFA63C61083,Comment
  338. {}
  339.  
  340. 211BD58E-6D44-49A5-AC4F-2DFA63C61083,Component
  341. {}
  342.  
  343. 211BD58E-6D44-49A5-AC4F-2DFA63C61083,FailureMessage
  344. {}
  345.  
  346. 211BD58E-6D44-49A5-AC4F-2DFA63C61083,Filename
  347. <%ProgramExecutable%>
  348.  
  349. 211BD58E-6D44-49A5-AC4F-2DFA63C61083,ID
  350. {}
  351.  
  352. 211BD58E-6D44-49A5-AC4F-2DFA63C61083,Operator
  353. exists
  354.  
  355. 242E27AA-551C-4796-B099-DFCAF9498E62,Action
  356. {Install Actions}
  357.  
  358. 242E27AA-551C-4796-B099-DFCAF9498E62,Active
  359. Yes
  360.  
  361. 242E27AA-551C-4796-B099-DFCAF9498E62,Alias
  362. {}
  363.  
  364. 242E27AA-551C-4796-B099-DFCAF9498E62,Comment
  365. {}
  366.  
  367. 242E27AA-551C-4796-B099-DFCAF9498E62,Component
  368. {}
  369.  
  370. 242E27AA-551C-4796-B099-DFCAF9498E62,Conditions
  371. {}
  372.  
  373. 242E27AA-551C-4796-B099-DFCAF9498E62,EvaluateConditions
  374. Yes
  375.  
  376. 242E27AA-551C-4796-B099-DFCAF9498E62,ExecuteAction
  377. {After Pane is Displayed}
  378.  
  379. 242E27AA-551C-4796-B099-DFCAF9498E62,ID
  380. {}
  381.  
  382. 242E27AA-551C-4796-B099-DFCAF9498E62,IgnoreErrors
  383. No
  384.  
  385. 25542048-E343-4AD5-B1A3-90B504E68373,Active
  386. Yes
  387.  
  388. 25542048-E343-4AD5-B1A3-90B504E68373,Alias
  389. {}
  390.  
  391. 25542048-E343-4AD5-B1A3-90B504E68373,CheckCondition
  392. {Before Pane is Displayed}
  393.  
  394. 25542048-E343-4AD5-B1A3-90B504E68373,Comment
  395. {}
  396.  
  397. 25542048-E343-4AD5-B1A3-90B504E68373,Component
  398. {}
  399.  
  400. 25542048-E343-4AD5-B1A3-90B504E68373,FailureMessage
  401. {}
  402.  
  403. 25542048-E343-4AD5-B1A3-90B504E68373,Filename
  404. <%ProgramExecutable%>
  405.  
  406. 25542048-E343-4AD5-B1A3-90B504E68373,ID
  407. {}
  408.  
  409. 25542048-E343-4AD5-B1A3-90B504E68373,Operator
  410. exists
  411.  
  412. 25A03054-7BF5-4B4A-A5E8-98C36C53A0F9,Active
  413. Yes
  414.  
  415. 25A03054-7BF5-4B4A-A5E8-98C36C53A0F9,Alias
  416. {}
  417.  
  418. 25A03054-7BF5-4B4A-A5E8-98C36C53A0F9,Comment
  419. {}
  420.  
  421. 25A03054-7BF5-4B4A-A5E8-98C36C53A0F9,Description,subst
  422. 1
  423.  
  424. 25A03054-7BF5-4B4A-A5E8-98C36C53A0F9,FileGroups
  425. BC9DDC29-8CDB-4C1E-A9F2-F002B44B6E20
  426.  
  427. 25A03054-7BF5-4B4A-A5E8-98C36C53A0F9,ID
  428. {}
  429.  
  430. 25A03054-7BF5-4B4A-A5E8-98C36C53A0F9,Name
  431. {Default Component}
  432.  
  433. 25A03054-7BF5-4B4A-A5E8-98C36C53A0F9,RequiredComponent
  434. Yes
  435.  
  436. 25A03054-7BF5-4B4A-A5E8-98C36C53A0F9,ShowComponent
  437. Yes
  438.  
  439. 26169907-3309-4C13-80BA-E6392EFA3702,AcceptRadiobutton,subst
  440. 0
  441.  
  442. 26169907-3309-4C13-80BA-E6392EFA3702,Active
  443. Yes
  444.  
  445. 26169907-3309-4C13-80BA-E6392EFA3702,Alias
  446. {}
  447.  
  448. 26169907-3309-4C13-80BA-E6392EFA3702,BackButton,subst
  449. 1
  450.  
  451. 26169907-3309-4C13-80BA-E6392EFA3702,Buttons
  452. Back/Next/Cancel
  453.  
  454. 26169907-3309-4C13-80BA-E6392EFA3702,CancelButton,subst
  455. 1
  456.  
  457. 26169907-3309-4C13-80BA-E6392EFA3702,Caption,subst
  458. 1
  459.  
  460. 26169907-3309-4C13-80BA-E6392EFA3702,Comment
  461. {}
  462.  
  463. 26169907-3309-4C13-80BA-E6392EFA3702,Component
  464. {}
  465.  
  466. 26169907-3309-4C13-80BA-E6392EFA3702,Conditions
  467. {0 conditions}
  468.  
  469. 26169907-3309-4C13-80BA-E6392EFA3702,DeclineRadiobutton,subst
  470. 0
  471.  
  472. 26169907-3309-4C13-80BA-E6392EFA3702,ID
  473. {}
  474.  
  475. 26169907-3309-4C13-80BA-E6392EFA3702,Icon
  476. <%Icon%>
  477.  
  478. 26169907-3309-4C13-80BA-E6392EFA3702,Message,subst
  479. 1
  480.  
  481. 26169907-3309-4C13-80BA-E6392EFA3702,NextButton,subst
  482. 1
  483.  
  484. 26169907-3309-4C13-80BA-E6392EFA3702,Subtitle,subst
  485. 1
  486.  
  487. 26169907-3309-4C13-80BA-E6392EFA3702,Text,subst
  488. 1
  489.  
  490. 26169907-3309-4C13-80BA-E6392EFA3702,Title,subst
  491. 1
  492.  
  493. 26169907-3309-4C13-80BA-E6392EFA3702,UserMustAcceptLicense
  494. Yes
  495.  
  496. 29E269AB-C3E3-4698-A8C4-0498DD1B541A,Active
  497. Yes
  498.  
  499. 29E269AB-C3E3-4698-A8C4-0498DD1B541A,Alias
  500. {}
  501.  
  502. 29E269AB-C3E3-4698-A8C4-0498DD1B541A,CheckCondition
  503. {Before Pane is Displayed}
  504.  
  505. 29E269AB-C3E3-4698-A8C4-0498DD1B541A,Comment
  506. {}
  507.  
  508. 29E269AB-C3E3-4698-A8C4-0498DD1B541A,Component
  509. {}
  510.  
  511. 29E269AB-C3E3-4698-A8C4-0498DD1B541A,FailureMessage
  512. {}
  513.  
  514. 29E269AB-C3E3-4698-A8C4-0498DD1B541A,ID
  515. {}
  516.  
  517. 29E269AB-C3E3-4698-A8C4-0498DD1B541A,Operator
  518. true
  519.  
  520. 29E269AB-C3E3-4698-A8C4-0498DD1B541A,String
  521. <%ViewReadme%>
  522.  
  523. 2F135310-2F98-4A7C-9DC1-ED574350AA47,Active
  524. Yes
  525.  
  526. 2F135310-2F98-4A7C-9DC1-ED574350AA47,Alias
  527. {}
  528.  
  529. 2F135310-2F98-4A7C-9DC1-ED574350AA47,CheckCondition
  530. {Before Pane is Displayed}
  531.  
  532. 2F135310-2F98-4A7C-9DC1-ED574350AA47,Comment
  533. {}
  534.  
  535. 2F135310-2F98-4A7C-9DC1-ED574350AA47,Component
  536. {}
  537.  
  538. 2F135310-2F98-4A7C-9DC1-ED574350AA47,FailureMessage
  539. {}
  540.  
  541. 2F135310-2F98-4A7C-9DC1-ED574350AA47,ID
  542. {}
  543.  
  544. 2F135310-2F98-4A7C-9DC1-ED574350AA47,Operator
  545. false
  546.  
  547. 2F135310-2F98-4A7C-9DC1-ED574350AA47,String
  548. <%LicenseAccepted%>
  549.  
  550. 354BBA54-2679-44CC-B528-BB123868926D,Active
  551. Yes
  552.  
  553. 354BBA54-2679-44CC-B528-BB123868926D,Alias
  554. {}
  555.  
  556. 354BBA54-2679-44CC-B528-BB123868926D,BackButton,subst
  557. 1
  558.  
  559. 354BBA54-2679-44CC-B528-BB123868926D,Buttons
  560. Back/Next/Cancel
  561.  
  562. 354BBA54-2679-44CC-B528-BB123868926D,CancelButton,subst
  563. 1
  564.  
  565. 354BBA54-2679-44CC-B528-BB123868926D,Caption,subst
  566. 1
  567.  
  568. 354BBA54-2679-44CC-B528-BB123868926D,Comment
  569. {}
  570.  
  571. 354BBA54-2679-44CC-B528-BB123868926D,Component
  572. {}
  573.  
  574. 354BBA54-2679-44CC-B528-BB123868926D,Conditions
  575. {0 conditions}
  576.  
  577. 354BBA54-2679-44CC-B528-BB123868926D,FileLabel,subst
  578. 1
  579.  
  580. 354BBA54-2679-44CC-B528-BB123868926D,ID
  581. {}
  582.  
  583. 354BBA54-2679-44CC-B528-BB123868926D,Icon
  584. <%Icon%>
  585.  
  586. 354BBA54-2679-44CC-B528-BB123868926D,Message,subst
  587. 1
  588.  
  589. 354BBA54-2679-44CC-B528-BB123868926D,NextButton,subst
  590. 1
  591.  
  592. 354BBA54-2679-44CC-B528-BB123868926D,ProgressValue,subst
  593. 1
  594.  
  595. 354BBA54-2679-44CC-B528-BB123868926D,Subtitle,subst
  596. 1
  597.  
  598. 354BBA54-2679-44CC-B528-BB123868926D,Title,subst
  599. 1
  600.  
  601. 376A656F-918F-49E1-9E01-3E734532FA0F,Active
  602. Yes
  603.  
  604. 376A656F-918F-49E1-9E01-3E734532FA0F,Alias
  605. {}
  606.  
  607. 376A656F-918F-49E1-9E01-3E734532FA0F,CheckCondition
  608. {Before Next Pane is Displayed}
  609.  
  610. 376A656F-918F-49E1-9E01-3E734532FA0F,Comment
  611. {}
  612.  
  613. 376A656F-918F-49E1-9E01-3E734532FA0F,Component
  614. {}
  615.  
  616. 376A656F-918F-49E1-9E01-3E734532FA0F,FailureMessage
  617. <%DirectoryPermissionText%>
  618.  
  619. 376A656F-918F-49E1-9E01-3E734532FA0F,Filename
  620. <%InstallDir%>
  621.  
  622. 376A656F-918F-49E1-9E01-3E734532FA0F,ID
  623. {}
  624.  
  625. 376A656F-918F-49E1-9E01-3E734532FA0F,Permission
  626. {can create}
  627.  
  628. 3801681B-4E3B-4AA7-8787-A96E18DD14B6,Active
  629. Yes
  630.  
  631. 3801681B-4E3B-4AA7-8787-A96E18DD14B6,Alias
  632. {}
  633.  
  634. 3801681B-4E3B-4AA7-8787-A96E18DD14B6,CheckCondition
  635. {Before Pane is Displayed}
  636.  
  637. 3801681B-4E3B-4AA7-8787-A96E18DD14B6,Comment
  638. {}
  639.  
  640. 3801681B-4E3B-4AA7-8787-A96E18DD14B6,Component
  641. {}
  642.  
  643. 3801681B-4E3B-4AA7-8787-A96E18DD14B6,FailureMessage
  644. {}
  645.  
  646. 3801681B-4E3B-4AA7-8787-A96E18DD14B6,ID
  647. {}
  648.  
  649. 3801681B-4E3B-4AA7-8787-A96E18DD14B6,Operator
  650. is
  651.  
  652. 3801681B-4E3B-4AA7-8787-A96E18DD14B6,Platform
  653. Windows
  654.  
  655. 41678FFA-A713-40E4-8E81-E374344D2971,Active
  656. Yes
  657.  
  658. 41678FFA-A713-40E4-8E81-E374344D2971,Alias
  659. {Startup Actions}
  660.  
  661. 41678FFA-A713-40E4-8E81-E374344D2971,Comment
  662. {}
  663.  
  664. 41678FFA-A713-40E4-8E81-E374344D2971,Conditions
  665. {}
  666.  
  667. 41678FFA-A713-40E4-8E81-E374344D2971,ID
  668. {}
  669.  
  670. 426B6A63-5AB7-42BB-B78F-3236D745399B,Active
  671. Yes
  672.  
  673. 426B6A63-5AB7-42BB-B78F-3236D745399B,Alias
  674. {}
  675.  
  676. 426B6A63-5AB7-42BB-B78F-3236D745399B,CheckCondition
  677. {Before Pane is Displayed}
  678.  
  679. 426B6A63-5AB7-42BB-B78F-3236D745399B,Comment
  680. {}
  681.  
  682. 426B6A63-5AB7-42BB-B78F-3236D745399B,Component
  683. {}
  684.  
  685. 426B6A63-5AB7-42BB-B78F-3236D745399B,FailureMessage
  686. {}
  687.  
  688. 426B6A63-5AB7-42BB-B78F-3236D745399B,ID
  689. {}
  690.  
  691. 426B6A63-5AB7-42BB-B78F-3236D745399B,Operator
  692. is
  693.  
  694. 426B6A63-5AB7-42BB-B78F-3236D745399B,Platform
  695. Windows
  696.  
  697. 4439AB66-CCD9-4421-BDB3-851F51B2DEE7,Active
  698. Yes
  699.  
  700. 4439AB66-CCD9-4421-BDB3-851F51B2DEE7,Alias
  701. {}
  702.  
  703. 4439AB66-CCD9-4421-BDB3-851F51B2DEE7,CheckCondition
  704. {Before Pane is Displayed}
  705.  
  706. 4439AB66-CCD9-4421-BDB3-851F51B2DEE7,Comment
  707. {}
  708.  
  709. 4439AB66-CCD9-4421-BDB3-851F51B2DEE7,Component
  710. {}
  711.  
  712. 4439AB66-CCD9-4421-BDB3-851F51B2DEE7,FailureMessage
  713. {}
  714.  
  715. 4439AB66-CCD9-4421-BDB3-851F51B2DEE7,Filename
  716. <%ProgramExecutable%>
  717.  
  718. 4439AB66-CCD9-4421-BDB3-851F51B2DEE7,ID
  719. {}
  720.  
  721. 4439AB66-CCD9-4421-BDB3-851F51B2DEE7,Operator
  722. exists
  723.  
  724. 44F378EE-B695-45D5-96FE-1BBC93596B1F,Active
  725. Yes
  726.  
  727. 44F378EE-B695-45D5-96FE-1BBC93596B1F,Alias
  728. {}
  729.  
  730. 44F378EE-B695-45D5-96FE-1BBC93596B1F,BackButton,subst
  731. 1
  732.  
  733. 44F378EE-B695-45D5-96FE-1BBC93596B1F,Buttons
  734. Back/Next/Cancel
  735.  
  736. 44F378EE-B695-45D5-96FE-1BBC93596B1F,CancelButton,subst
  737. 1
  738.  
  739. 44F378EE-B695-45D5-96FE-1BBC93596B1F,Caption,subst
  740. 1
  741.  
  742. 44F378EE-B695-45D5-96FE-1BBC93596B1F,Comment
  743. {}
  744.  
  745. 44F378EE-B695-45D5-96FE-1BBC93596B1F,Component
  746. {}
  747.  
  748. 44F378EE-B695-45D5-96FE-1BBC93596B1F,Conditions
  749. {}
  750.  
  751. 44F378EE-B695-45D5-96FE-1BBC93596B1F,FileLabel,subst
  752. 1
  753.  
  754. 44F378EE-B695-45D5-96FE-1BBC93596B1F,ID
  755. {}
  756.  
  757. 44F378EE-B695-45D5-96FE-1BBC93596B1F,Icon
  758. <%Icon%>
  759.  
  760. 44F378EE-B695-45D5-96FE-1BBC93596B1F,Message,subst
  761. 1
  762.  
  763. 44F378EE-B695-45D5-96FE-1BBC93596B1F,NextButton,subst
  764. 1
  765.  
  766. 44F378EE-B695-45D5-96FE-1BBC93596B1F,ProgressValue,subst
  767. 1
  768.  
  769. 44F378EE-B695-45D5-96FE-1BBC93596B1F,Subtitle,subst
  770. 1
  771.  
  772. 44F378EE-B695-45D5-96FE-1BBC93596B1F,Title,subst
  773. 1
  774.  
  775. 4A354C44-1D80-4EFC-991B-1550F2A9E791,Active
  776. Yes
  777.  
  778. 4A354C44-1D80-4EFC-991B-1550F2A9E791,Alias
  779. {}
  780.  
  781. 4A354C44-1D80-4EFC-991B-1550F2A9E791,Comment
  782. {}
  783.  
  784. 4A354C44-1D80-4EFC-991B-1550F2A9E791,Components
  785. 25A03054-7BF5-4B4A-A5E8-98C36C53A0F9
  786.  
  787. 4A354C44-1D80-4EFC-991B-1550F2A9E791,Description,subst
  788. 1
  789.  
  790. 4A354C44-1D80-4EFC-991B-1550F2A9E791,ID
  791. {}
  792.  
  793. 4A354C44-1D80-4EFC-991B-1550F2A9E791,Name
  794. Custom
  795.  
  796. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,Active
  797. Yes
  798.  
  799. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,Alias
  800. {}
  801.  
  802. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,Comment
  803. {}
  804.  
  805. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,Comments
  806. {}
  807.  
  808. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,Component
  809. {}
  810.  
  811. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,Conditions
  812. {}
  813.  
  814. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,Contact
  815. {}
  816.  
  817. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,DisplayIcon
  818. <%ProgramExecutable%>
  819.  
  820. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,DisplayName
  821. <%AppName%>
  822.  
  823. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,DisplayVersion
  824. <%Version%>
  825.  
  826. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,ExecuteAction
  827. {After Pane is Displayed}
  828.  
  829. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,HelpLink
  830. {}
  831.  
  832. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,HelpTelephone
  833. {}
  834.  
  835. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,ID
  836. {}
  837.  
  838. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,IgnoreErrors
  839. No
  840.  
  841. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,InstallDate
  842. {<%Date %Y%m%d%>}
  843.  
  844. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,InstallLocation
  845. <%InstallDir%>
  846.  
  847. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,InstallSource
  848. <%InstallSource%>
  849.  
  850. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,Publisher
  851. <%Company%>
  852.  
  853. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,QuietUninstallString
  854. {<%Uninstaller%> -S}
  855.  
  856. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,Readme
  857. <%ProgramReadme%>
  858.  
  859. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,RegistryKeyName
  860. <%ApplicationID%>
  861.  
  862. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,URLInfoAbout
  863. <%ApplicationURL%>
  864.  
  865. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,URLUpdateInfo
  866. <%ApplicationURL%>
  867.  
  868. 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70,UninstallString
  869. <%Uninstaller%>
  870.  
  871. 4C3FF654-9F5C-4679-B71D-F23E14F61844,Active
  872. Yes
  873.  
  874. 4C3FF654-9F5C-4679-B71D-F23E14F61844,Alias
  875. {}
  876.  
  877. 4C3FF654-9F5C-4679-B71D-F23E14F61844,BackButton,subst
  878. 1
  879.  
  880. 4C3FF654-9F5C-4679-B71D-F23E14F61844,Buttons
  881. Next/Cancel
  882.  
  883. 4C3FF654-9F5C-4679-B71D-F23E14F61844,CancelButton,subst
  884. 1
  885.  
  886. 4C3FF654-9F5C-4679-B71D-F23E14F61844,Caption,subst
  887. 1
  888.  
  889. 4C3FF654-9F5C-4679-B71D-F23E14F61844,Comment
  890. {}
  891.  
  892. 4C3FF654-9F5C-4679-B71D-F23E14F61844,Component
  893. {}
  894.  
  895. 4C3FF654-9F5C-4679-B71D-F23E14F61844,Conditions
  896. {0 conditions}
  897.  
  898. 4C3FF654-9F5C-4679-B71D-F23E14F61844,ID
  899. {}
  900.  
  901. 4C3FF654-9F5C-4679-B71D-F23E14F61844,Image
  902. <%Image%>
  903.  
  904. 4C3FF654-9F5C-4679-B71D-F23E14F61844,Message,subst
  905. 1
  906.  
  907. 4C3FF654-9F5C-4679-B71D-F23E14F61844,NextButton,subst
  908. 1
  909.  
  910. 4C3FF654-9F5C-4679-B71D-F23E14F61844,WizardOptions
  911. {-bg white -separator 0}
  912.  
  913. 4C97A1FF-3B60-4E13-9D4E-020C32F5A661,Active
  914. Yes
  915.  
  916. 4C97A1FF-3B60-4E13-9D4E-020C32F5A661,Alias
  917. {}
  918.  
  919. 4C97A1FF-3B60-4E13-9D4E-020C32F5A661,Comment
  920. {}
  921.  
  922. 4C97A1FF-3B60-4E13-9D4E-020C32F5A661,Component
  923. {}
  924.  
  925. 4C97A1FF-3B60-4E13-9D4E-020C32F5A661,Conditions
  926. {}
  927.  
  928. 4C97A1FF-3B60-4E13-9D4E-020C32F5A661,ExecuteAction
  929. {After Pane is Displayed}
  930.  
  931. 4C97A1FF-3B60-4E13-9D4E-020C32F5A661,ID
  932. {}
  933.  
  934. 4C97A1FF-3B60-4E13-9D4E-020C32F5A661,IgnoreErrors
  935. No
  936.  
  937. 4C97A1FF-3B60-4E13-9D4E-020C32F5A661,State
  938. disabled
  939.  
  940. 4C97A1FF-3B60-4E13-9D4E-020C32F5A661,Text
  941. {}
  942.  
  943. 4C97A1FF-3B60-4E13-9D4E-020C32F5A661,Widget
  944. {Back Button;Next Button}
  945.  
  946. 4D90F974-8C14-4E2F-B458-82FE9510F546,Active
  947. Yes
  948.  
  949. 4D90F974-8C14-4E2F-B458-82FE9510F546,Alias
  950. {}
  951.  
  952. 4D90F974-8C14-4E2F-B458-82FE9510F546,CommandLineArguments
  953. {}
  954.  
  955. 4D90F974-8C14-4E2F-B458-82FE9510F546,Comment
  956. {}
  957.  
  958. 4D90F974-8C14-4E2F-B458-82FE9510F546,Component
  959. {}
  960.  
  961. 4D90F974-8C14-4E2F-B458-82FE9510F546,Conditions
  962. {}
  963.  
  964. 4D90F974-8C14-4E2F-B458-82FE9510F546,ExecuteAction
  965. {After Pane is Displayed}
  966.  
  967. 4D90F974-8C14-4E2F-B458-82FE9510F546,ID
  968. {}
  969.  
  970. 4D90F974-8C14-4E2F-B458-82FE9510F546,IconPath
  971. {}
  972.  
  973. 4D90F974-8C14-4E2F-B458-82FE9510F546,IconPathIndex
  974. 0
  975.  
  976. 4D90F974-8C14-4E2F-B458-82FE9510F546,IgnoreErrors
  977. No
  978.  
  979. 4D90F974-8C14-4E2F-B458-82FE9510F546,ShortcutDirectory
  980. <%ProgramFolder%>
  981.  
  982. 4D90F974-8C14-4E2F-B458-82FE9510F546,ShortcutName
  983. {Uninstall <%AppName%>}
  984.  
  985. 4D90F974-8C14-4E2F-B458-82FE9510F546,TargetFileName
  986. <%Uninstaller%>
  987.  
  988. 4D90F974-8C14-4E2F-B458-82FE9510F546,WindowState
  989. normal
  990.  
  991. 4D90F974-8C14-4E2F-B458-82FE9510F546,WorkingDirectory
  992. <%InstallDir%>
  993.  
  994. 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4,Active
  995. Yes
  996.  
  997. 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4,Alias
  998. {}
  999.  
  1000. 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4,Background
  1001. white
  1002.  
  1003. 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4,Checked
  1004. {}
  1005.  
  1006. 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4,Comment
  1007. {}
  1008.  
  1009. 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4,Component
  1010. {}
  1011.  
  1012. 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4,Conditions
  1013. {}
  1014.  
  1015. 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4,ExecuteAction
  1016. {After Pane is Displayed}
  1017.  
  1018. 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4,Height
  1019. {}
  1020.  
  1021. 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4,ID
  1022. {}
  1023.  
  1024. 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4,IgnoreErrors
  1025. No
  1026.  
  1027. 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4,Text,subst
  1028. 1
  1029.  
  1030. 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4,Type
  1031. checkbutton
  1032.  
  1033. 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4,Value
  1034. {}
  1035.  
  1036. 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4,VirtualText
  1037. LaunchApplication
  1038.  
  1039. 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4,Width
  1040. {}
  1041.  
  1042. 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4,X
  1043. 185
  1044.  
  1045. 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4,Y
  1046. 160
  1047.  
  1048. 4F4A68D9-4A26-4E38-93FC-94F3EB6DCAE7,Active
  1049. Yes
  1050.  
  1051. 4F4A68D9-4A26-4E38-93FC-94F3EB6DCAE7,Alias
  1052. {}
  1053.  
  1054. 4F4A68D9-4A26-4E38-93FC-94F3EB6DCAE7,CheckCondition
  1055. {Before Pane is Displayed}
  1056.  
  1057. 4F4A68D9-4A26-4E38-93FC-94F3EB6DCAE7,Comment
  1058. {}
  1059.  
  1060. 4F4A68D9-4A26-4E38-93FC-94F3EB6DCAE7,Component
  1061. {}
  1062.  
  1063. 4F4A68D9-4A26-4E38-93FC-94F3EB6DCAE7,FailureMessage
  1064. {}
  1065.  
  1066. 4F4A68D9-4A26-4E38-93FC-94F3EB6DCAE7,Filename
  1067. <%ProgramExecutable%>
  1068.  
  1069. 4F4A68D9-4A26-4E38-93FC-94F3EB6DCAE7,ID
  1070. {}
  1071.  
  1072. 4F4A68D9-4A26-4E38-93FC-94F3EB6DCAE7,Operator
  1073. exists
  1074.  
  1075. 4F8BE818-346C-4637-AE4C-4A6B7C48CB74,Active
  1076. Yes
  1077.  
  1078. 4F8BE818-346C-4637-AE4C-4A6B7C48CB74,Alias
  1079. {}
  1080.  
  1081. 4F8BE818-346C-4637-AE4C-4A6B7C48CB74,Comment
  1082. {}
  1083.  
  1084. 4F8BE818-346C-4637-AE4C-4A6B7C48CB74,Component
  1085. {}
  1086.  
  1087. 4F8BE818-346C-4637-AE4C-4A6B7C48CB74,Conditions
  1088. {}
  1089.  
  1090. 4F8BE818-346C-4637-AE4C-4A6B7C48CB74,ExecuteAction
  1091. {After Pane is Displayed}
  1092.  
  1093. 4F8BE818-346C-4637-AE4C-4A6B7C48CB74,ID
  1094. {}
  1095.  
  1096. 4F8BE818-346C-4637-AE4C-4A6B7C48CB74,IgnoreErrors
  1097. No
  1098.  
  1099. 4F8BE818-346C-4637-AE4C-4A6B7C48CB74,Message
  1100. <%BuildUninstallText%>
  1101.  
  1102. 4F8BE818-346C-4637-AE4C-4A6B7C48CB74,UninstallDirectory
  1103. <%InstallDir%>
  1104.  
  1105. 50748934-8AC2-4A3C-AC85-D701FAC60C49,Active
  1106. Yes
  1107.  
  1108. 50748934-8AC2-4A3C-AC85-D701FAC60C49,Alias
  1109. {}
  1110.  
  1111. 50748934-8AC2-4A3C-AC85-D701FAC60C49,CheckCondition
  1112. {Before Pane is Displayed}
  1113.  
  1114. 50748934-8AC2-4A3C-AC85-D701FAC60C49,Comment
  1115. {}
  1116.  
  1117. 50748934-8AC2-4A3C-AC85-D701FAC60C49,Component
  1118. {}
  1119.  
  1120. 50748934-8AC2-4A3C-AC85-D701FAC60C49,FailureMessage
  1121. {}
  1122.  
  1123. 50748934-8AC2-4A3C-AC85-D701FAC60C49,Filename
  1124. <%ProgramExecutable%>
  1125.  
  1126. 50748934-8AC2-4A3C-AC85-D701FAC60C49,ID
  1127. {}
  1128.  
  1129. 50748934-8AC2-4A3C-AC85-D701FAC60C49,Operator
  1130. exists
  1131.  
  1132. 5315266E-E68B-435E-AFBC-E218FDC19369,Active
  1133. Yes
  1134.  
  1135. 5315266E-E68B-435E-AFBC-E218FDC19369,Alias
  1136. {}
  1137.  
  1138. 5315266E-E68B-435E-AFBC-E218FDC19369,Comment
  1139. {}
  1140.  
  1141. 5315266E-E68B-435E-AFBC-E218FDC19369,Component
  1142. {}
  1143.  
  1144. 5315266E-E68B-435E-AFBC-E218FDC19369,Conditions
  1145. {}
  1146.  
  1147. 5315266E-E68B-435E-AFBC-E218FDC19369,ExecuteAction
  1148. {After Pane is Displayed}
  1149.  
  1150. 5315266E-E68B-435E-AFBC-E218FDC19369,ID
  1151. {}
  1152.  
  1153. 5315266E-E68B-435E-AFBC-E218FDC19369,IgnoreErrors
  1154. No
  1155.  
  1156. 5315266E-E68B-435E-AFBC-E218FDC19369,State
  1157. disabled
  1158.  
  1159. 5315266E-E68B-435E-AFBC-E218FDC19369,Text
  1160. {}
  1161.  
  1162. 5315266E-E68B-435E-AFBC-E218FDC19369,Widget
  1163. {Back Button;Next Button}
  1164.  
  1165. 55DB7606-259D-4B3C-A3C1-5CCF6C12638C,Active
  1166. Yes
  1167.  
  1168. 55DB7606-259D-4B3C-A3C1-5CCF6C12638C,Alias
  1169. {}
  1170.  
  1171. 55DB7606-259D-4B3C-A3C1-5CCF6C12638C,Background
  1172. white
  1173.  
  1174. 55DB7606-259D-4B3C-A3C1-5CCF6C12638C,Checked
  1175. {}
  1176.  
  1177. 55DB7606-259D-4B3C-A3C1-5CCF6C12638C,Comment
  1178. {}
  1179.  
  1180. 55DB7606-259D-4B3C-A3C1-5CCF6C12638C,Component
  1181. {}
  1182.  
  1183. 55DB7606-259D-4B3C-A3C1-5CCF6C12638C,Conditions
  1184. {}
  1185.  
  1186. 55DB7606-259D-4B3C-A3C1-5CCF6C12638C,ExecuteAction
  1187. {After Pane is Displayed}
  1188.  
  1189. 55DB7606-259D-4B3C-A3C1-5CCF6C12638C,Height
  1190. {}
  1191.  
  1192. 55DB7606-259D-4B3C-A3C1-5CCF6C12638C,ID
  1193. {}
  1194.  
  1195. 55DB7606-259D-4B3C-A3C1-5CCF6C12638C,IgnoreErrors
  1196. No
  1197.  
  1198. 55DB7606-259D-4B3C-A3C1-5CCF6C12638C,Text,subst
  1199. 1
  1200.  
  1201. 55DB7606-259D-4B3C-A3C1-5CCF6C12638C,Type
  1202. checkbutton
  1203.  
  1204. 55DB7606-259D-4B3C-A3C1-5CCF6C12638C,Value
  1205. {}
  1206.  
  1207. 55DB7606-259D-4B3C-A3C1-5CCF6C12638C,VirtualText
  1208. LaunchApplication
  1209.  
  1210. 55DB7606-259D-4B3C-A3C1-5CCF6C12638C,Width
  1211. {}
  1212.  
  1213. 55DB7606-259D-4B3C-A3C1-5CCF6C12638C,X
  1214. 185
  1215.  
  1216. 55DB7606-259D-4B3C-A3C1-5CCF6C12638C,Y
  1217. 160
  1218.  
  1219. 5DD477BC-16FE-4DDC-9161-E30D7E1DB549,Active
  1220. Yes
  1221.  
  1222. 5DD477BC-16FE-4DDC-9161-E30D7E1DB549,Alias
  1223. {Finish Actions}
  1224.  
  1225. 5DD477BC-16FE-4DDC-9161-E30D7E1DB549,Comment
  1226. {}
  1227.  
  1228. 5DD477BC-16FE-4DDC-9161-E30D7E1DB549,Conditions
  1229. {}
  1230.  
  1231. 5DD477BC-16FE-4DDC-9161-E30D7E1DB549,ID
  1232. {}
  1233.  
  1234. 5F9F234B-8C55-46E5-B883-78843926A386,Active
  1235. Yes
  1236.  
  1237. 5F9F234B-8C55-46E5-B883-78843926A386,Alias
  1238. {}
  1239.  
  1240. 5F9F234B-8C55-46E5-B883-78843926A386,CheckCondition
  1241. {Before Pane is Displayed}
  1242.  
  1243. 5F9F234B-8C55-46E5-B883-78843926A386,Comment
  1244. {}
  1245.  
  1246. 5F9F234B-8C55-46E5-B883-78843926A386,Component
  1247. {}
  1248.  
  1249. 5F9F234B-8C55-46E5-B883-78843926A386,FailureMessage
  1250. {}
  1251.  
  1252. 5F9F234B-8C55-46E5-B883-78843926A386,ID
  1253. {}
  1254.  
  1255. 5F9F234B-8C55-46E5-B883-78843926A386,Operator
  1256. false
  1257.  
  1258. 5F9F234B-8C55-46E5-B883-78843926A386,String
  1259. <%InstallStopped%>
  1260.  
  1261. 625FF735-46E7-411C-ABFE-D0BE7677001B,Active
  1262. Yes
  1263.  
  1264. 625FF735-46E7-411C-ABFE-D0BE7677001B,Alias
  1265. {}
  1266.  
  1267. 625FF735-46E7-411C-ABFE-D0BE7677001B,CheckCondition
  1268. {Before Pane is Displayed}
  1269.  
  1270. 625FF735-46E7-411C-ABFE-D0BE7677001B,Comment
  1271. {}
  1272.  
  1273. 625FF735-46E7-411C-ABFE-D0BE7677001B,Component
  1274. {}
  1275.  
  1276. 625FF735-46E7-411C-ABFE-D0BE7677001B,FailureMessage
  1277. {}
  1278.  
  1279. 625FF735-46E7-411C-ABFE-D0BE7677001B,Filename
  1280. <%ProgramExecutable%>
  1281.  
  1282. 625FF735-46E7-411C-ABFE-D0BE7677001B,ID
  1283. {}
  1284.  
  1285. 625FF735-46E7-411C-ABFE-D0BE7677001B,Operator
  1286. exists
  1287.  
  1288. 62EF759C-DEDA-4D58-AED0-90D0974F1657,Active
  1289. Yes
  1290.  
  1291. 62EF759C-DEDA-4D58-AED0-90D0974F1657,Alias
  1292. {Install Actions}
  1293.  
  1294. 62EF759C-DEDA-4D58-AED0-90D0974F1657,Comment
  1295. {}
  1296.  
  1297. 62EF759C-DEDA-4D58-AED0-90D0974F1657,Conditions
  1298. {}
  1299.  
  1300. 62EF759C-DEDA-4D58-AED0-90D0974F1657,ID
  1301. {}
  1302.  
  1303. 642021C6-FD45-486A-91AB-8A333627A3D9,Active
  1304. Yes
  1305.  
  1306. 642021C6-FD45-486A-91AB-8A333627A3D9,Alias
  1307. {}
  1308.  
  1309. 642021C6-FD45-486A-91AB-8A333627A3D9,CheckCondition
  1310. {Before Pane is Displayed}
  1311.  
  1312. 642021C6-FD45-486A-91AB-8A333627A3D9,Comment
  1313. {}
  1314.  
  1315. 642021C6-FD45-486A-91AB-8A333627A3D9,Component
  1316. {}
  1317.  
  1318. 642021C6-FD45-486A-91AB-8A333627A3D9,FailureMessage
  1319. {}
  1320.  
  1321. 642021C6-FD45-486A-91AB-8A333627A3D9,ID
  1322. {}
  1323.  
  1324. 642021C6-FD45-486A-91AB-8A333627A3D9,Operator
  1325. false
  1326.  
  1327. 642021C6-FD45-486A-91AB-8A333627A3D9,String
  1328. <%InstallStopped%>
  1329.  
  1330. 662CEDC2-7F2F-44F4-B260-A7990F8F4E4F,Active
  1331. Yes
  1332.  
  1333. 662CEDC2-7F2F-44F4-B260-A7990F8F4E4F,Alias
  1334. {}
  1335.  
  1336. 662CEDC2-7F2F-44F4-B260-A7990F8F4E4F,CheckCondition
  1337. {Before Pane is Displayed}
  1338.  
  1339. 662CEDC2-7F2F-44F4-B260-A7990F8F4E4F,Comment
  1340. {}
  1341.  
  1342. 662CEDC2-7F2F-44F4-B260-A7990F8F4E4F,Component
  1343. {}
  1344.  
  1345. 662CEDC2-7F2F-44F4-B260-A7990F8F4E4F,FailureMessage
  1346. {}
  1347.  
  1348. 662CEDC2-7F2F-44F4-B260-A7990F8F4E4F,ID
  1349. {}
  1350.  
  1351. 662CEDC2-7F2F-44F4-B260-A7990F8F4E4F,Operator
  1352. false
  1353.  
  1354. 662CEDC2-7F2F-44F4-B260-A7990F8F4E4F,String
  1355. <%InstallStopped%>
  1356.  
  1357. 6A4B5CE4-BBF6-4444-8593-E188A69FA768,Active
  1358. Yes
  1359.  
  1360. 6A4B5CE4-BBF6-4444-8593-E188A69FA768,Alias
  1361. {}
  1362.  
  1363. 6A4B5CE4-BBF6-4444-8593-E188A69FA768,Background
  1364. white
  1365.  
  1366. 6A4B5CE4-BBF6-4444-8593-E188A69FA768,Checked
  1367. {}
  1368.  
  1369. 6A4B5CE4-BBF6-4444-8593-E188A69FA768,Comment
  1370. {}
  1371.  
  1372. 6A4B5CE4-BBF6-4444-8593-E188A69FA768,Component
  1373. {}
  1374.  
  1375. 6A4B5CE4-BBF6-4444-8593-E188A69FA768,Conditions
  1376. {}
  1377.  
  1378. 6A4B5CE4-BBF6-4444-8593-E188A69FA768,ExecuteAction
  1379. {After Pane is Displayed}
  1380.  
  1381. 6A4B5CE4-BBF6-4444-8593-E188A69FA768,Height
  1382. {}
  1383.  
  1384. 6A4B5CE4-BBF6-4444-8593-E188A69FA768,ID
  1385. {}
  1386.  
  1387. 6A4B5CE4-BBF6-4444-8593-E188A69FA768,IgnoreErrors
  1388. No
  1389.  
  1390. 6A4B5CE4-BBF6-4444-8593-E188A69FA768,Text,subst
  1391. 1
  1392.  
  1393. 6A4B5CE4-BBF6-4444-8593-E188A69FA768,Type
  1394. checkbutton
  1395.  
  1396. 6A4B5CE4-BBF6-4444-8593-E188A69FA768,Value
  1397. {}
  1398.  
  1399. 6A4B5CE4-BBF6-4444-8593-E188A69FA768,VirtualText
  1400. ViewReadme
  1401.  
  1402. 6A4B5CE4-BBF6-4444-8593-E188A69FA768,Width
  1403. {}
  1404.  
  1405. 6A4B5CE4-BBF6-4444-8593-E188A69FA768,X
  1406. 185
  1407.  
  1408. 6A4B5CE4-BBF6-4444-8593-E188A69FA768,Y
  1409. 140
  1410.  
  1411. 71ED690B-1531-4FC1-A869-F347967DE87B,Active
  1412. Yes
  1413.  
  1414. 71ED690B-1531-4FC1-A869-F347967DE87B,Alias
  1415. {}
  1416.  
  1417. 71ED690B-1531-4FC1-A869-F347967DE87B,CheckCondition
  1418. {Before Pane is Displayed}
  1419.  
  1420. 71ED690B-1531-4FC1-A869-F347967DE87B,Comment
  1421. {}
  1422.  
  1423. 71ED690B-1531-4FC1-A869-F347967DE87B,Component
  1424. {}
  1425.  
  1426. 71ED690B-1531-4FC1-A869-F347967DE87B,FailureMessage
  1427. {}
  1428.  
  1429. 71ED690B-1531-4FC1-A869-F347967DE87B,ID
  1430. {}
  1431.  
  1432. 71ED690B-1531-4FC1-A869-F347967DE87B,Operator
  1433. false
  1434.  
  1435. 71ED690B-1531-4FC1-A869-F347967DE87B,String
  1436. <%InstallStopped%>
  1437.  
  1438. 75C4743C-92B4-41B2-9162-2929B3A08869,Active
  1439. Yes
  1440.  
  1441. 75C4743C-92B4-41B2-9162-2929B3A08869,AdditionalArguments
  1442. {}
  1443.  
  1444. 75C4743C-92B4-41B2-9162-2929B3A08869,Alias
  1445. {}
  1446.  
  1447. 75C4743C-92B4-41B2-9162-2929B3A08869,CommandLineArguments
  1448. {}
  1449.  
  1450. 75C4743C-92B4-41B2-9162-2929B3A08869,Comment
  1451. {}
  1452.  
  1453. 75C4743C-92B4-41B2-9162-2929B3A08869,Component
  1454. {}
  1455.  
  1456. 75C4743C-92B4-41B2-9162-2929B3A08869,Conditions
  1457. {}
  1458.  
  1459. 75C4743C-92B4-41B2-9162-2929B3A08869,ExecuteAction
  1460. {After Pane is Displayed}
  1461.  
  1462. 75C4743C-92B4-41B2-9162-2929B3A08869,ID
  1463. {}
  1464.  
  1465. 75C4743C-92B4-41B2-9162-2929B3A08869,IconPath
  1466. {}
  1467.  
  1468. 75C4743C-92B4-41B2-9162-2929B3A08869,IconPathIndex
  1469. 0
  1470.  
  1471. 75C4743C-92B4-41B2-9162-2929B3A08869,IgnoreErrors
  1472. No
  1473.  
  1474. 75C4743C-92B4-41B2-9162-2929B3A08869,InstallForAllUsers
  1475. No
  1476.  
  1477. 75C4743C-92B4-41B2-9162-2929B3A08869,ShortcutName
  1478. <%AppName%>
  1479.  
  1480. 75C4743C-92B4-41B2-9162-2929B3A08869,ShortcutType
  1481. Application
  1482.  
  1483. 75C4743C-92B4-41B2-9162-2929B3A08869,TargetFileName
  1484. <%ProgramExecutable%>
  1485.  
  1486. 75C4743C-92B4-41B2-9162-2929B3A08869,WindowState
  1487. normal
  1488.  
  1489. 75C4743C-92B4-41B2-9162-2929B3A08869,WorkingDirectory
  1490. <%InstallDir%>
  1491.  
  1492. 77FEE21B-4F91-4C17-B6FF-FA8A07FEAE20,Active
  1493. Yes
  1494.  
  1495. 77FEE21B-4F91-4C17-B6FF-FA8A07FEAE20,Alias
  1496. {}
  1497.  
  1498. 77FEE21B-4F91-4C17-B6FF-FA8A07FEAE20,CheckCondition
  1499. {Before Pane is Displayed}
  1500.  
  1501. 77FEE21B-4F91-4C17-B6FF-FA8A07FEAE20,Comment
  1502. {}
  1503.  
  1504. 77FEE21B-4F91-4C17-B6FF-FA8A07FEAE20,Component
  1505. {}
  1506.  
  1507. 77FEE21B-4F91-4C17-B6FF-FA8A07FEAE20,FailureMessage
  1508. {}
  1509.  
  1510. 77FEE21B-4F91-4C17-B6FF-FA8A07FEAE20,Filename
  1511. <%ProgramExecutable%>
  1512.  
  1513. 77FEE21B-4F91-4C17-B6FF-FA8A07FEAE20,ID
  1514. {}
  1515.  
  1516. 77FEE21B-4F91-4C17-B6FF-FA8A07FEAE20,Operator
  1517. exists
  1518.  
  1519. 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8,Active
  1520. Yes
  1521.  
  1522. 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8,Alias
  1523. {}
  1524.  
  1525. 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8,Anchor
  1526. center
  1527.  
  1528. 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8,Caption,subst
  1529. 1
  1530.  
  1531. 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8,CloseButton,subst
  1532. 1
  1533.  
  1534. 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8,Comment
  1535. {}
  1536.  
  1537. 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8,Component
  1538. {}
  1539.  
  1540. 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8,Conditions
  1541. {}
  1542.  
  1543. 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8,ExecuteAction
  1544. {After Pane is Displayed}
  1545.  
  1546. 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8,GrabFocus
  1547. Yes
  1548.  
  1549. 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8,Height
  1550. 300
  1551.  
  1552. 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8,ID
  1553. {}
  1554.  
  1555. 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8,IgnoreErrors
  1556. No
  1557.  
  1558. 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8,Message,subst
  1559. 1
  1560.  
  1561. 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8,TextFile
  1562. <%ProgramReadme%>
  1563.  
  1564. 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8,TextWrap
  1565. word
  1566.  
  1567. 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8,Title,subst
  1568. 1
  1569.  
  1570. 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8,WaitOnWindow
  1571. Yes
  1572.  
  1573. 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8,Width
  1574. 400
  1575.  
  1576. 78C0D25B-104F-4227-ADF5-C342079844AD,Active
  1577. Yes
  1578.  
  1579. 78C0D25B-104F-4227-ADF5-C342079844AD,Alias
  1580. {}
  1581.  
  1582. 78C0D25B-104F-4227-ADF5-C342079844AD,CheckCondition
  1583. {Before Pane is Displayed}
  1584.  
  1585. 78C0D25B-104F-4227-ADF5-C342079844AD,Comment
  1586. {}
  1587.  
  1588. 78C0D25B-104F-4227-ADF5-C342079844AD,Component
  1589. {}
  1590.  
  1591. 78C0D25B-104F-4227-ADF5-C342079844AD,FailureMessage
  1592. {}
  1593.  
  1594. 78C0D25B-104F-4227-ADF5-C342079844AD,Filename
  1595. <%ProgramExecutable%>
  1596.  
  1597. 78C0D25B-104F-4227-ADF5-C342079844AD,ID
  1598. {}
  1599.  
  1600. 78C0D25B-104F-4227-ADF5-C342079844AD,Operator
  1601. exists
  1602.  
  1603. 7F7C9C19-3650-4E50-8B27-32C9644DF62B,Active
  1604. Yes
  1605.  
  1606. 7F7C9C19-3650-4E50-8B27-32C9644DF62B,Alias
  1607. {}
  1608.  
  1609. 7F7C9C19-3650-4E50-8B27-32C9644DF62B,BackButton,subst
  1610. 1
  1611.  
  1612. 7F7C9C19-3650-4E50-8B27-32C9644DF62B,Buttons
  1613. Back/Next/Cancel
  1614.  
  1615. 7F7C9C19-3650-4E50-8B27-32C9644DF62B,CancelButton,subst
  1616. 1
  1617.  
  1618. 7F7C9C19-3650-4E50-8B27-32C9644DF62B,Caption,subst
  1619. 1
  1620.  
  1621. 7F7C9C19-3650-4E50-8B27-32C9644DF62B,Comment
  1622. {}
  1623.  
  1624. 7F7C9C19-3650-4E50-8B27-32C9644DF62B,Component
  1625. {}
  1626.  
  1627. 7F7C9C19-3650-4E50-8B27-32C9644DF62B,Conditions
  1628. {0 conditions}
  1629.  
  1630. 7F7C9C19-3650-4E50-8B27-32C9644DF62B,ID
  1631. {}
  1632.  
  1633. 7F7C9C19-3650-4E50-8B27-32C9644DF62B,Icon
  1634. <%Icon%>
  1635.  
  1636. 7F7C9C19-3650-4E50-8B27-32C9644DF62B,Message,subst
  1637. 1
  1638.  
  1639. 7F7C9C19-3650-4E50-8B27-32C9644DF62B,NextButton,subst
  1640. 1
  1641.  
  1642. 7F7C9C19-3650-4E50-8B27-32C9644DF62B,Subtitle,subst
  1643. 1
  1644.  
  1645. 7F7C9C19-3650-4E50-8B27-32C9644DF62B,Text,subst
  1646. 1
  1647.  
  1648. 7F7C9C19-3650-4E50-8B27-32C9644DF62B,Title,subst
  1649. 1
  1650.  
  1651. 80E90A24-8A32-4E27-9C5C-3B5EF6283D1F,Active
  1652. Yes
  1653.  
  1654. 80E90A24-8A32-4E27-9C5C-3B5EF6283D1F,Alias
  1655. {}
  1656.  
  1657. 80E90A24-8A32-4E27-9C5C-3B5EF6283D1F,CheckCondition
  1658. {Before Pane is Displayed}
  1659.  
  1660. 80E90A24-8A32-4E27-9C5C-3B5EF6283D1F,Comment
  1661. {}
  1662.  
  1663. 80E90A24-8A32-4E27-9C5C-3B5EF6283D1F,Component
  1664. {}
  1665.  
  1666. 80E90A24-8A32-4E27-9C5C-3B5EF6283D1F,FailureMessage
  1667. {}
  1668.  
  1669. 80E90A24-8A32-4E27-9C5C-3B5EF6283D1F,Filename
  1670. <%ProgramExecutable%>
  1671.  
  1672. 80E90A24-8A32-4E27-9C5C-3B5EF6283D1F,ID
  1673. {}
  1674.  
  1675. 80E90A24-8A32-4E27-9C5C-3B5EF6283D1F,Operator
  1676. exists
  1677.  
  1678. 85CBEC09-95F0-4510-8130-23292CD4E280,Active
  1679. Yes
  1680.  
  1681. 85CBEC09-95F0-4510-8130-23292CD4E280,Alias
  1682. {}
  1683.  
  1684. 85CBEC09-95F0-4510-8130-23292CD4E280,Background
  1685. white
  1686.  
  1687. 85CBEC09-95F0-4510-8130-23292CD4E280,Checked
  1688. {}
  1689.  
  1690. 85CBEC09-95F0-4510-8130-23292CD4E280,Comment
  1691. {}
  1692.  
  1693. 85CBEC09-95F0-4510-8130-23292CD4E280,Component
  1694. {}
  1695.  
  1696. 85CBEC09-95F0-4510-8130-23292CD4E280,Conditions
  1697. {}
  1698.  
  1699. 85CBEC09-95F0-4510-8130-23292CD4E280,ExecuteAction
  1700. {After Pane is Displayed}
  1701.  
  1702. 85CBEC09-95F0-4510-8130-23292CD4E280,Height
  1703. {}
  1704.  
  1705. 85CBEC09-95F0-4510-8130-23292CD4E280,ID
  1706. {}
  1707.  
  1708. 85CBEC09-95F0-4510-8130-23292CD4E280,IgnoreErrors
  1709. No
  1710.  
  1711. 85CBEC09-95F0-4510-8130-23292CD4E280,Text,subst
  1712. 1
  1713.  
  1714. 85CBEC09-95F0-4510-8130-23292CD4E280,Type
  1715. checkbutton
  1716.  
  1717. 85CBEC09-95F0-4510-8130-23292CD4E280,Value
  1718. {}
  1719.  
  1720. 85CBEC09-95F0-4510-8130-23292CD4E280,VirtualText
  1721. CreateDesktopShortcut
  1722.  
  1723. 85CBEC09-95F0-4510-8130-23292CD4E280,Width
  1724. {}
  1725.  
  1726. 85CBEC09-95F0-4510-8130-23292CD4E280,X
  1727. 185
  1728.  
  1729. 85CBEC09-95F0-4510-8130-23292CD4E280,Y
  1730. 180
  1731.  
  1732. 8E64750C-6A5E-4955-9FA0-396CC703201B,Active
  1733. Yes
  1734.  
  1735. 8E64750C-6A5E-4955-9FA0-396CC703201B,Alias
  1736. {}
  1737.  
  1738. 8E64750C-6A5E-4955-9FA0-396CC703201B,CheckCondition
  1739. {Before Pane is Displayed}
  1740.  
  1741. 8E64750C-6A5E-4955-9FA0-396CC703201B,Comment
  1742. {}
  1743.  
  1744. 8E64750C-6A5E-4955-9FA0-396CC703201B,Component
  1745. {}
  1746.  
  1747. 8E64750C-6A5E-4955-9FA0-396CC703201B,FailureMessage
  1748. {}
  1749.  
  1750. 8E64750C-6A5E-4955-9FA0-396CC703201B,ID
  1751. {}
  1752.  
  1753. 8E64750C-6A5E-4955-9FA0-396CC703201B,Operator
  1754. true
  1755.  
  1756. 8E64750C-6A5E-4955-9FA0-396CC703201B,String
  1757. <%LaunchApplication%>
  1758.  
  1759. 9B3864C7-F41B-43F6-B5FB-86D60573F3EA,Active
  1760. Yes
  1761.  
  1762. 9B3864C7-F41B-43F6-B5FB-86D60573F3EA,Alias
  1763. {}
  1764.  
  1765. 9B3864C7-F41B-43F6-B5FB-86D60573F3EA,CheckCondition
  1766. {Before Pane is Displayed}
  1767.  
  1768. 9B3864C7-F41B-43F6-B5FB-86D60573F3EA,Comment
  1769. {}
  1770.  
  1771. 9B3864C7-F41B-43F6-B5FB-86D60573F3EA,Component
  1772. {}
  1773.  
  1774. 9B3864C7-F41B-43F6-B5FB-86D60573F3EA,FailureMessage
  1775. {}
  1776.  
  1777. 9B3864C7-F41B-43F6-B5FB-86D60573F3EA,ID
  1778. {}
  1779.  
  1780. 9B3864C7-F41B-43F6-B5FB-86D60573F3EA,Operator
  1781. is
  1782.  
  1783. 9B3864C7-F41B-43F6-B5FB-86D60573F3EA,Platform
  1784. Windows
  1785.  
  1786. 9D77E823-EBFA-474A-9016-D327212A026B,Active
  1787. Yes
  1788.  
  1789. 9D77E823-EBFA-474A-9016-D327212A026B,Alias
  1790. {}
  1791.  
  1792. 9D77E823-EBFA-474A-9016-D327212A026B,CheckCondition
  1793. {Before Pane is Displayed}
  1794.  
  1795. 9D77E823-EBFA-474A-9016-D327212A026B,Comment
  1796. {}
  1797.  
  1798. 9D77E823-EBFA-474A-9016-D327212A026B,Component
  1799. {}
  1800.  
  1801. 9D77E823-EBFA-474A-9016-D327212A026B,FailureMessage
  1802. {}
  1803.  
  1804. 9D77E823-EBFA-474A-9016-D327212A026B,ID
  1805. {}
  1806.  
  1807. 9D77E823-EBFA-474A-9016-D327212A026B,Operator
  1808. false
  1809.  
  1810. 9D77E823-EBFA-474A-9016-D327212A026B,String
  1811. <%SilentMode%>
  1812.  
  1813. 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D,Active
  1814. Yes
  1815.  
  1816. 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D,Alias
  1817. {}
  1818.  
  1819. 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D,BackButton,subst
  1820. 1
  1821.  
  1822. 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D,BrowseButton,subst
  1823. 1
  1824.  
  1825. 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D,BrowseText,subst
  1826. 1
  1827.  
  1828. 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D,Buttons
  1829. Back/Next/Cancel
  1830.  
  1831. 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D,CancelButton,subst
  1832. 1
  1833.  
  1834. 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D,Caption,subst
  1835. 1
  1836.  
  1837. 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D,Comment
  1838. {}
  1839.  
  1840. 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D,Component
  1841. {}
  1842.  
  1843. 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D,Conditions
  1844. {1 condition}
  1845.  
  1846. 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D,DestinationLabel,subst
  1847. 0
  1848.  
  1849. 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D,ID
  1850. {}
  1851.  
  1852. 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D,Icon
  1853. <%Icon%>
  1854.  
  1855. 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D,Message,subst
  1856. 1
  1857.  
  1858. 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D,NextButton,subst
  1859. 1
  1860.  
  1861. 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D,Subtitle,subst
  1862. 1
  1863.  
  1864. 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D,Title,subst
  1865. 1
  1866.  
  1867. A2E136B8-114D-4028-876B-5F7DE6E5D06C,Active
  1868. Yes
  1869.  
  1870. A2E136B8-114D-4028-876B-5F7DE6E5D06C,Alias
  1871. {}
  1872.  
  1873. A2E136B8-114D-4028-876B-5F7DE6E5D06C,BackButton,subst
  1874. 1
  1875.  
  1876. A2E136B8-114D-4028-876B-5F7DE6E5D06C,Buttons
  1877. Next/Cancel
  1878.  
  1879. A2E136B8-114D-4028-876B-5F7DE6E5D06C,CancelButton,subst
  1880. 1
  1881.  
  1882. A2E136B8-114D-4028-876B-5F7DE6E5D06C,Caption,subst
  1883. 1
  1884.  
  1885. A2E136B8-114D-4028-876B-5F7DE6E5D06C,Comment
  1886. {}
  1887.  
  1888. A2E136B8-114D-4028-876B-5F7DE6E5D06C,Component
  1889. {}
  1890.  
  1891. A2E136B8-114D-4028-876B-5F7DE6E5D06C,Conditions
  1892. {0 conditions}
  1893.  
  1894. A2E136B8-114D-4028-876B-5F7DE6E5D06C,ID
  1895. {}
  1896.  
  1897. A2E136B8-114D-4028-876B-5F7DE6E5D06C,Image
  1898. <%Image%>
  1899.  
  1900. A2E136B8-114D-4028-876B-5F7DE6E5D06C,Message,subst
  1901. 1
  1902.  
  1903. A2E136B8-114D-4028-876B-5F7DE6E5D06C,NextButton,subst
  1904. 1
  1905.  
  1906. A2E136B8-114D-4028-876B-5F7DE6E5D06C,WizardOptions
  1907. {-bg white -separator 0}
  1908.  
  1909. A41FE23D-88CA-44B9-B9A7-18C2F2879E8D,Active
  1910. Yes
  1911.  
  1912. A41FE23D-88CA-44B9-B9A7-18C2F2879E8D,Alias
  1913. {}
  1914.  
  1915. A41FE23D-88CA-44B9-B9A7-18C2F2879E8D,Background
  1916. white
  1917.  
  1918. A41FE23D-88CA-44B9-B9A7-18C2F2879E8D,Checked
  1919. {}
  1920.  
  1921. A41FE23D-88CA-44B9-B9A7-18C2F2879E8D,Comment
  1922. {}
  1923.  
  1924. A41FE23D-88CA-44B9-B9A7-18C2F2879E8D,Component
  1925. {}
  1926.  
  1927. A41FE23D-88CA-44B9-B9A7-18C2F2879E8D,Conditions
  1928. {}
  1929.  
  1930. A41FE23D-88CA-44B9-B9A7-18C2F2879E8D,ExecuteAction
  1931. {After Pane is Displayed}
  1932.  
  1933. A41FE23D-88CA-44B9-B9A7-18C2F2879E8D,Height
  1934. {}
  1935.  
  1936. A41FE23D-88CA-44B9-B9A7-18C2F2879E8D,ID
  1937. {}
  1938.  
  1939. A41FE23D-88CA-44B9-B9A7-18C2F2879E8D,IgnoreErrors
  1940. No
  1941.  
  1942. A41FE23D-88CA-44B9-B9A7-18C2F2879E8D,Text,subst
  1943. 1
  1944.  
  1945. A41FE23D-88CA-44B9-B9A7-18C2F2879E8D,Type
  1946. checkbutton
  1947.  
  1948. A41FE23D-88CA-44B9-B9A7-18C2F2879E8D,Value
  1949. {}
  1950.  
  1951. A41FE23D-88CA-44B9-B9A7-18C2F2879E8D,VirtualText
  1952. ViewReadme
  1953.  
  1954. A41FE23D-88CA-44B9-B9A7-18C2F2879E8D,Width
  1955. {}
  1956.  
  1957. A41FE23D-88CA-44B9-B9A7-18C2F2879E8D,X
  1958. 185
  1959.  
  1960. A41FE23D-88CA-44B9-B9A7-18C2F2879E8D,Y
  1961. 140
  1962.  
  1963. A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3,Active
  1964. Yes
  1965.  
  1966. A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3,Alias
  1967. {}
  1968.  
  1969. A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3,BackButton,subst
  1970. 1
  1971.  
  1972. A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3,Buttons
  1973. Next/Cancel
  1974.  
  1975. A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3,CancelButton,subst
  1976. 1
  1977.  
  1978. A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3,Caption,subst
  1979. 1
  1980.  
  1981. A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3,Comment
  1982. {}
  1983.  
  1984. A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3,Component
  1985. {}
  1986.  
  1987. A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3,Conditions
  1988. {}
  1989.  
  1990. A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3,ID
  1991. {}
  1992.  
  1993. A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3,Image
  1994. <%Image%>
  1995.  
  1996. A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3,Message,subst
  1997. 1
  1998.  
  1999. A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3,NextButton,subst
  2000. 1
  2001.  
  2002. A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3,WizardOptions
  2003. {-bg white -separator 0}
  2004.  
  2005. A5A6DE1F-6058-4D53-ACB1-C0E411A485AE,Active
  2006. Yes
  2007.  
  2008. A5A6DE1F-6058-4D53-ACB1-C0E411A485AE,Alias
  2009. {}
  2010.  
  2011. A5A6DE1F-6058-4D53-ACB1-C0E411A485AE,Comment
  2012. {}
  2013.  
  2014. A5A6DE1F-6058-4D53-ACB1-C0E411A485AE,Component
  2015. {}
  2016.  
  2017. A5A6DE1F-6058-4D53-ACB1-C0E411A485AE,Conditions
  2018. {}
  2019.  
  2020. A5A6DE1F-6058-4D53-ACB1-C0E411A485AE,ExecuteAction
  2021. {After Pane is Displayed}
  2022.  
  2023. A5A6DE1F-6058-4D53-ACB1-C0E411A485AE,ID
  2024. {}
  2025.  
  2026. A5A6DE1F-6058-4D53-ACB1-C0E411A485AE,IgnoreErrors
  2027. No
  2028.  
  2029. A5A6DE1F-6058-4D53-ACB1-C0E411A485AE,ProgramCommandLine
  2030. <%ProgramExecutable%>
  2031.  
  2032. A5A6DE1F-6058-4D53-ACB1-C0E411A485AE,ProgressiveOutputWidget
  2033. {}
  2034.  
  2035. A5A6DE1F-6058-4D53-ACB1-C0E411A485AE,ResultVirtualText
  2036. ExternalProgramResult
  2037.  
  2038. A5A6DE1F-6058-4D53-ACB1-C0E411A485AE,ShowProgressiveOutput
  2039. No
  2040.  
  2041. A5A6DE1F-6058-4D53-ACB1-C0E411A485AE,StatusVirtualText
  2042. ExternalProgramStatus
  2043.  
  2044. A5A6DE1F-6058-4D53-ACB1-C0E411A485AE,WaitForProgram
  2045. No
  2046.  
  2047. A5A6DE1F-6058-4D53-ACB1-C0E411A485AE,WorkingDirectory
  2048. <%InstallDir%>
  2049.  
  2050. A6185DCF-A645-44CE-BCA8-AD0CF2DD3183,Active
  2051. Yes
  2052.  
  2053. A6185DCF-A645-44CE-BCA8-AD0CF2DD3183,Alias
  2054. {}
  2055.  
  2056. A6185DCF-A645-44CE-BCA8-AD0CF2DD3183,Comment
  2057. {}
  2058.  
  2059. A6185DCF-A645-44CE-BCA8-AD0CF2DD3183,Component
  2060. {}
  2061.  
  2062. A6185DCF-A645-44CE-BCA8-AD0CF2DD3183,Conditions
  2063. {}
  2064.  
  2065. A6185DCF-A645-44CE-BCA8-AD0CF2DD3183,ExecuteAction
  2066. {After Pane is Displayed}
  2067.  
  2068. A6185DCF-A645-44CE-BCA8-AD0CF2DD3183,ID
  2069. {}
  2070.  
  2071. A6185DCF-A645-44CE-BCA8-AD0CF2DD3183,IgnoreErrors
  2072. No
  2073.  
  2074. A9D2ED78-502D-4FA8-A26A-C93DE0CAE4F3,Active
  2075. Yes
  2076.  
  2077. A9D2ED78-502D-4FA8-A26A-C93DE0CAE4F3,Alias
  2078. {}
  2079.  
  2080. A9D2ED78-502D-4FA8-A26A-C93DE0CAE4F3,CommandLineArguments
  2081. {}
  2082.  
  2083. A9D2ED78-502D-4FA8-A26A-C93DE0CAE4F3,Comment
  2084. {}
  2085.  
  2086. A9D2ED78-502D-4FA8-A26A-C93DE0CAE4F3,Component
  2087. {}
  2088.  
  2089. A9D2ED78-502D-4FA8-A26A-C93DE0CAE4F3,Conditions
  2090. {}
  2091.  
  2092. A9D2ED78-502D-4FA8-A26A-C93DE0CAE4F3,ExecuteAction
  2093. {After Pane is Displayed}
  2094.  
  2095. A9D2ED78-502D-4FA8-A26A-C93DE0CAE4F3,ID
  2096. {}
  2097.  
  2098. A9D2ED78-502D-4FA8-A26A-C93DE0CAE4F3,IconPath
  2099. {}
  2100.  
  2101. A9D2ED78-502D-4FA8-A26A-C93DE0CAE4F3,IconPathIndex
  2102. 0
  2103.  
  2104. A9D2ED78-502D-4FA8-A26A-C93DE0CAE4F3,IgnoreErrors
  2105. No
  2106.  
  2107. A9D2ED78-502D-4FA8-A26A-C93DE0CAE4F3,ShortcutDirectory
  2108. <%ProgramFolder%>
  2109.  
  2110. A9D2ED78-502D-4FA8-A26A-C93DE0CAE4F3,ShortcutName
  2111. <%AppName%>
  2112.  
  2113. A9D2ED78-502D-4FA8-A26A-C93DE0CAE4F3,TargetFileName
  2114. <%ProgramExecutable%>
  2115.  
  2116. A9D2ED78-502D-4FA8-A26A-C93DE0CAE4F3,WindowState
  2117. normal
  2118.  
  2119. A9D2ED78-502D-4FA8-A26A-C93DE0CAE4F3,WorkingDirectory
  2120. <%InstallDir%>
  2121.  
  2122. AB94C219-6C76-4908-9CCE-99A4E7AB484F,Active
  2123. Yes
  2124.  
  2125. AB94C219-6C76-4908-9CCE-99A4E7AB484F,Alias
  2126. {}
  2127.  
  2128. AB94C219-6C76-4908-9CCE-99A4E7AB484F,CheckCondition
  2129. {Before Pane is Displayed}
  2130.  
  2131. AB94C219-6C76-4908-9CCE-99A4E7AB484F,Comment
  2132. {}
  2133.  
  2134. AB94C219-6C76-4908-9CCE-99A4E7AB484F,Component
  2135. {}
  2136.  
  2137. AB94C219-6C76-4908-9CCE-99A4E7AB484F,FailureMessage
  2138. {}
  2139.  
  2140. AB94C219-6C76-4908-9CCE-99A4E7AB484F,Filename
  2141. <%ProgramReadme%>
  2142.  
  2143. AB94C219-6C76-4908-9CCE-99A4E7AB484F,ID
  2144. {}
  2145.  
  2146. AB94C219-6C76-4908-9CCE-99A4E7AB484F,Operator
  2147. exists
  2148.  
  2149. B8C49671-1167-476C-90AF-509528EAC2EE,Active
  2150. Yes
  2151.  
  2152. B8C49671-1167-476C-90AF-509528EAC2EE,Alias
  2153. {}
  2154.  
  2155. B8C49671-1167-476C-90AF-509528EAC2EE,CheckCondition
  2156. {Before Pane is Displayed}
  2157.  
  2158. B8C49671-1167-476C-90AF-509528EAC2EE,Comment
  2159. {}
  2160.  
  2161. B8C49671-1167-476C-90AF-509528EAC2EE,Component
  2162. {}
  2163.  
  2164. B8C49671-1167-476C-90AF-509528EAC2EE,FailureMessage
  2165. {}
  2166.  
  2167. B8C49671-1167-476C-90AF-509528EAC2EE,ID
  2168. {}
  2169.  
  2170. B8C49671-1167-476C-90AF-509528EAC2EE,Operator
  2171. true
  2172.  
  2173. B8C49671-1167-476C-90AF-509528EAC2EE,String
  2174. <%CreateQuickLaunchShortcut%>
  2175.  
  2176. B8D63777-F7F8-4C24-901D-8024A7AB2F06,Active
  2177. Yes
  2178.  
  2179. B8D63777-F7F8-4C24-901D-8024A7AB2F06,Alias
  2180. {}
  2181.  
  2182. B8D63777-F7F8-4C24-901D-8024A7AB2F06,CheckCondition
  2183. {Before Pane is Displayed}
  2184.  
  2185. B8D63777-F7F8-4C24-901D-8024A7AB2F06,Comment
  2186. {}
  2187.  
  2188. B8D63777-F7F8-4C24-901D-8024A7AB2F06,Component
  2189. {}
  2190.  
  2191. B8D63777-F7F8-4C24-901D-8024A7AB2F06,FailureMessage
  2192. {}
  2193.  
  2194. B8D63777-F7F8-4C24-901D-8024A7AB2F06,ID
  2195. {}
  2196.  
  2197. B8D63777-F7F8-4C24-901D-8024A7AB2F06,Operator
  2198. true
  2199.  
  2200. B8D63777-F7F8-4C24-901D-8024A7AB2F06,String
  2201. <%CreateDesktopShortcut%>
  2202.  
  2203. BA400D3F-D7F5-4B08-96DC-091A0416E08E,Active
  2204. Yes
  2205.  
  2206. BA400D3F-D7F5-4B08-96DC-091A0416E08E,Alias
  2207. {}
  2208.  
  2209. BA400D3F-D7F5-4B08-96DC-091A0416E08E,Comment
  2210. {}
  2211.  
  2212. BA400D3F-D7F5-4B08-96DC-091A0416E08E,Component
  2213. {}
  2214.  
  2215. BA400D3F-D7F5-4B08-96DC-091A0416E08E,Conditions
  2216. {}
  2217.  
  2218. BA400D3F-D7F5-4B08-96DC-091A0416E08E,ExecuteAction
  2219. {After Pane is Displayed}
  2220.  
  2221. BA400D3F-D7F5-4B08-96DC-091A0416E08E,ID
  2222. {}
  2223.  
  2224. BA400D3F-D7F5-4B08-96DC-091A0416E08E,IgnoreErrors
  2225. No
  2226.  
  2227. BC9DDC29-8CDB-4C1E-A9F2-F002B44B6E20,Active
  2228. Yes
  2229.  
  2230. BC9DDC29-8CDB-4C1E-A9F2-F002B44B6E20,Alias
  2231. {}
  2232.  
  2233. BC9DDC29-8CDB-4C1E-A9F2-F002B44B6E20,Attributes
  2234. {}
  2235.  
  2236. BC9DDC29-8CDB-4C1E-A9F2-F002B44B6E20,Comment
  2237. {}
  2238.  
  2239. BC9DDC29-8CDB-4C1E-A9F2-F002B44B6E20,Destination
  2240. <%InstallDir%>
  2241.  
  2242. BC9DDC29-8CDB-4C1E-A9F2-F002B44B6E20,FileUpdateMethod
  2243. {Update files with more recent dates}
  2244.  
  2245. BC9DDC29-8CDB-4C1E-A9F2-F002B44B6E20,ID
  2246. {}
  2247.  
  2248. BC9DDC29-8CDB-4C1E-A9F2-F002B44B6E20,Name
  2249. {Program Files}
  2250.  
  2251. BC9DDC29-8CDB-4C1E-A9F2-F002B44B6E20,Permissions
  2252. {}
  2253.  
  2254. BC9DDC29-8CDB-4C1E-A9F2-F002B44B6E20,Size
  2255. 117983
  2256.  
  2257. BC9DDC29-8CDB-4C1E-A9F2-F002B44B6E20,Version
  2258. {}
  2259.  
  2260. BFF0AA9C-A6A8-490D-81E8-6BDF94581355,Active
  2261. Yes
  2262.  
  2263. BFF0AA9C-A6A8-490D-81E8-6BDF94581355,Alias
  2264. {}
  2265.  
  2266. BFF0AA9C-A6A8-490D-81E8-6BDF94581355,CheckCondition
  2267. {Before Pane is Displayed}
  2268.  
  2269. BFF0AA9C-A6A8-490D-81E8-6BDF94581355,Comment
  2270. {}
  2271.  
  2272. BFF0AA9C-A6A8-490D-81E8-6BDF94581355,Component
  2273. {}
  2274.  
  2275. BFF0AA9C-A6A8-490D-81E8-6BDF94581355,FailureMessage
  2276. {}
  2277.  
  2278. BFF0AA9C-A6A8-490D-81E8-6BDF94581355,ID
  2279. {}
  2280.  
  2281. BFF0AA9C-A6A8-490D-81E8-6BDF94581355,Operator
  2282. false
  2283.  
  2284. BFF0AA9C-A6A8-490D-81E8-6BDF94581355,String
  2285. <%SilentMode%>
  2286.  
  2287. C33F8E7D-7970-43C4-B653-FFA8CE170EC8,Active
  2288. Yes
  2289.  
  2290. C33F8E7D-7970-43C4-B653-FFA8CE170EC8,Alias
  2291. {}
  2292.  
  2293. C33F8E7D-7970-43C4-B653-FFA8CE170EC8,CheckCondition
  2294. {Before Pane is Displayed}
  2295.  
  2296. C33F8E7D-7970-43C4-B653-FFA8CE170EC8,Comment
  2297. {}
  2298.  
  2299. C33F8E7D-7970-43C4-B653-FFA8CE170EC8,Component
  2300. {}
  2301.  
  2302. C33F8E7D-7970-43C4-B653-FFA8CE170EC8,FailureMessage
  2303. {}
  2304.  
  2305. C33F8E7D-7970-43C4-B653-FFA8CE170EC8,ID
  2306. {}
  2307.  
  2308. C33F8E7D-7970-43C4-B653-FFA8CE170EC8,Operator
  2309. is
  2310.  
  2311. C33F8E7D-7970-43C4-B653-FFA8CE170EC8,Platform
  2312. Windows
  2313.  
  2314. C66D6544-4FCE-4697-B0E4-4B6F3A462973,Active
  2315. Yes
  2316.  
  2317. C66D6544-4FCE-4697-B0E4-4B6F3A462973,Alias
  2318. {}
  2319.  
  2320. C66D6544-4FCE-4697-B0E4-4B6F3A462973,CheckCondition
  2321. {Before Pane is Displayed}
  2322.  
  2323. C66D6544-4FCE-4697-B0E4-4B6F3A462973,Comment
  2324. {}
  2325.  
  2326. C66D6544-4FCE-4697-B0E4-4B6F3A462973,Component
  2327. {}
  2328.  
  2329. C66D6544-4FCE-4697-B0E4-4B6F3A462973,FailureMessage
  2330. {}
  2331.  
  2332. C66D6544-4FCE-4697-B0E4-4B6F3A462973,ID
  2333. {}
  2334.  
  2335. C66D6544-4FCE-4697-B0E4-4B6F3A462973,Operator
  2336. false
  2337.  
  2338. C66D6544-4FCE-4697-B0E4-4B6F3A462973,String
  2339. <%InstallStopped%>
  2340.  
  2341. C91C5668-E984-4541-871C-CF6194F3F71F,Active
  2342. Yes
  2343.  
  2344. C91C5668-E984-4541-871C-CF6194F3F71F,Alias
  2345. {}
  2346.  
  2347. C91C5668-E984-4541-871C-CF6194F3F71F,Background
  2348. white
  2349.  
  2350. C91C5668-E984-4541-871C-CF6194F3F71F,Checked
  2351. {}
  2352.  
  2353. C91C5668-E984-4541-871C-CF6194F3F71F,Comment
  2354. {}
  2355.  
  2356. C91C5668-E984-4541-871C-CF6194F3F71F,Component
  2357. {}
  2358.  
  2359. C91C5668-E984-4541-871C-CF6194F3F71F,Conditions
  2360. {}
  2361.  
  2362. C91C5668-E984-4541-871C-CF6194F3F71F,ExecuteAction
  2363. {After Pane is Displayed}
  2364.  
  2365. C91C5668-E984-4541-871C-CF6194F3F71F,Height
  2366. {}
  2367.  
  2368. C91C5668-E984-4541-871C-CF6194F3F71F,ID
  2369. {}
  2370.  
  2371. C91C5668-E984-4541-871C-CF6194F3F71F,IgnoreErrors
  2372. No
  2373.  
  2374. C91C5668-E984-4541-871C-CF6194F3F71F,Text,subst
  2375. 1
  2376.  
  2377. C91C5668-E984-4541-871C-CF6194F3F71F,Type
  2378. checkbutton
  2379.  
  2380. C91C5668-E984-4541-871C-CF6194F3F71F,Value
  2381. {}
  2382.  
  2383. C91C5668-E984-4541-871C-CF6194F3F71F,VirtualText
  2384. CreateDesktopShortcut
  2385.  
  2386. C91C5668-E984-4541-871C-CF6194F3F71F,Width
  2387. {}
  2388.  
  2389. C91C5668-E984-4541-871C-CF6194F3F71F,X
  2390. 185
  2391.  
  2392. C91C5668-E984-4541-871C-CF6194F3F71F,Y
  2393. 180
  2394.  
  2395. CBF10125-0D47-4DBB-9630-0CA6FDA9489B,Action
  2396. {Install Actions}
  2397.  
  2398. CBF10125-0D47-4DBB-9630-0CA6FDA9489B,Active
  2399. Yes
  2400.  
  2401. CBF10125-0D47-4DBB-9630-0CA6FDA9489B,Alias
  2402. {}
  2403.  
  2404. CBF10125-0D47-4DBB-9630-0CA6FDA9489B,Comment
  2405. {}
  2406.  
  2407. CBF10125-0D47-4DBB-9630-0CA6FDA9489B,Component
  2408. {}
  2409.  
  2410. CBF10125-0D47-4DBB-9630-0CA6FDA9489B,Conditions
  2411. {}
  2412.  
  2413. CBF10125-0D47-4DBB-9630-0CA6FDA9489B,EvaluateConditions
  2414. Yes
  2415.  
  2416. CBF10125-0D47-4DBB-9630-0CA6FDA9489B,ExecuteAction
  2417. {After Pane is Displayed}
  2418.  
  2419. CBF10125-0D47-4DBB-9630-0CA6FDA9489B,ID
  2420. {}
  2421.  
  2422. CBF10125-0D47-4DBB-9630-0CA6FDA9489B,IgnoreErrors
  2423. No
  2424.  
  2425. D0A37977-56A8-4296-9659-512D495FF25E,Active
  2426. Yes
  2427.  
  2428. D0A37977-56A8-4296-9659-512D495FF25E,Alias
  2429. {}
  2430.  
  2431. D0A37977-56A8-4296-9659-512D495FF25E,Background
  2432. white
  2433.  
  2434. D0A37977-56A8-4296-9659-512D495FF25E,Checked
  2435. {}
  2436.  
  2437. D0A37977-56A8-4296-9659-512D495FF25E,Comment
  2438. {}
  2439.  
  2440. D0A37977-56A8-4296-9659-512D495FF25E,Component
  2441. {}
  2442.  
  2443. D0A37977-56A8-4296-9659-512D495FF25E,Conditions
  2444. {}
  2445.  
  2446. D0A37977-56A8-4296-9659-512D495FF25E,ExecuteAction
  2447. {After Pane is Displayed}
  2448.  
  2449. D0A37977-56A8-4296-9659-512D495FF25E,Height
  2450. {}
  2451.  
  2452. D0A37977-56A8-4296-9659-512D495FF25E,ID
  2453. {}
  2454.  
  2455. D0A37977-56A8-4296-9659-512D495FF25E,IgnoreErrors
  2456. No
  2457.  
  2458. D0A37977-56A8-4296-9659-512D495FF25E,Text,subst
  2459. 1
  2460.  
  2461. D0A37977-56A8-4296-9659-512D495FF25E,Type
  2462. checkbutton
  2463.  
  2464. D0A37977-56A8-4296-9659-512D495FF25E,Value
  2465. {}
  2466.  
  2467. D0A37977-56A8-4296-9659-512D495FF25E,VirtualText
  2468. CreateQuickLaunchShortcut
  2469.  
  2470. D0A37977-56A8-4296-9659-512D495FF25E,Width
  2471. {}
  2472.  
  2473. D0A37977-56A8-4296-9659-512D495FF25E,X
  2474. 185
  2475.  
  2476. D0A37977-56A8-4296-9659-512D495FF25E,Y
  2477. 200
  2478.  
  2479. D1224075-F20A-4015-A39F-9DCE7111AF5B,Active
  2480. Yes
  2481.  
  2482. D1224075-F20A-4015-A39F-9DCE7111AF5B,Alias
  2483. {}
  2484.  
  2485. D1224075-F20A-4015-A39F-9DCE7111AF5B,Background
  2486. white
  2487.  
  2488. D1224075-F20A-4015-A39F-9DCE7111AF5B,Checked
  2489. {}
  2490.  
  2491. D1224075-F20A-4015-A39F-9DCE7111AF5B,Comment
  2492. {}
  2493.  
  2494. D1224075-F20A-4015-A39F-9DCE7111AF5B,Component
  2495. {}
  2496.  
  2497. D1224075-F20A-4015-A39F-9DCE7111AF5B,Conditions
  2498. {}
  2499.  
  2500. D1224075-F20A-4015-A39F-9DCE7111AF5B,ExecuteAction
  2501. {After Pane is Displayed}
  2502.  
  2503. D1224075-F20A-4015-A39F-9DCE7111AF5B,Height
  2504. {}
  2505.  
  2506. D1224075-F20A-4015-A39F-9DCE7111AF5B,ID
  2507. {}
  2508.  
  2509. D1224075-F20A-4015-A39F-9DCE7111AF5B,IgnoreErrors
  2510. No
  2511.  
  2512. D1224075-F20A-4015-A39F-9DCE7111AF5B,Text,subst
  2513. 1
  2514.  
  2515. D1224075-F20A-4015-A39F-9DCE7111AF5B,Type
  2516. checkbutton
  2517.  
  2518. D1224075-F20A-4015-A39F-9DCE7111AF5B,Value
  2519. {}
  2520.  
  2521. D1224075-F20A-4015-A39F-9DCE7111AF5B,VirtualText
  2522. CreateQuickLaunchShortcut
  2523.  
  2524. D1224075-F20A-4015-A39F-9DCE7111AF5B,Width
  2525. {}
  2526.  
  2527. D1224075-F20A-4015-A39F-9DCE7111AF5B,X
  2528. 185
  2529.  
  2530. D1224075-F20A-4015-A39F-9DCE7111AF5B,Y
  2531. 200
  2532.  
  2533. D34364B6-8486-412D-914A-34A01B029D62,Active
  2534. Yes
  2535.  
  2536. D34364B6-8486-412D-914A-34A01B029D62,Alias
  2537. {}
  2538.  
  2539. D34364B6-8486-412D-914A-34A01B029D62,CheckCondition
  2540. {Before Pane is Displayed}
  2541.  
  2542. D34364B6-8486-412D-914A-34A01B029D62,Comment
  2543. {}
  2544.  
  2545. D34364B6-8486-412D-914A-34A01B029D62,Component
  2546. {}
  2547.  
  2548. D34364B6-8486-412D-914A-34A01B029D62,FailureMessage
  2549. {}
  2550.  
  2551. D34364B6-8486-412D-914A-34A01B029D62,Filename
  2552. <%ProgramReadme%>
  2553.  
  2554. D34364B6-8486-412D-914A-34A01B029D62,ID
  2555. {}
  2556.  
  2557. D34364B6-8486-412D-914A-34A01B029D62,Operator
  2558. exists
  2559.  
  2560. D9504B73-531B-4DAB-87F0-811824D98680,Active
  2561. Yes
  2562.  
  2563. D9504B73-531B-4DAB-87F0-811824D98680,Alias
  2564. {}
  2565.  
  2566. D9504B73-531B-4DAB-87F0-811824D98680,Comment
  2567. {}
  2568.  
  2569. D9504B73-531B-4DAB-87F0-811824D98680,Component
  2570. {}
  2571.  
  2572. D9504B73-531B-4DAB-87F0-811824D98680,Conditions
  2573. {}
  2574.  
  2575. D9504B73-531B-4DAB-87F0-811824D98680,ExecuteAction
  2576. {After Pane is Displayed}
  2577.  
  2578. D9504B73-531B-4DAB-87F0-811824D98680,ID
  2579. {}
  2580.  
  2581. D9504B73-531B-4DAB-87F0-811824D98680,IgnoreErrors
  2582. No
  2583.  
  2584. DC88586F-6788-4678-A90C-4D79A8DE9BE4,Active
  2585. Yes
  2586.  
  2587. DC88586F-6788-4678-A90C-4D79A8DE9BE4,Alias
  2588. {}
  2589.  
  2590. DC88586F-6788-4678-A90C-4D79A8DE9BE4,CheckCondition
  2591. {Before Pane is Displayed}
  2592.  
  2593. DC88586F-6788-4678-A90C-4D79A8DE9BE4,Comment
  2594. {}
  2595.  
  2596. DC88586F-6788-4678-A90C-4D79A8DE9BE4,Component
  2597. {}
  2598.  
  2599. DC88586F-6788-4678-A90C-4D79A8DE9BE4,FailureMessage
  2600. {}
  2601.  
  2602. DC88586F-6788-4678-A90C-4D79A8DE9BE4,ID
  2603. {}
  2604.  
  2605. DC88586F-6788-4678-A90C-4D79A8DE9BE4,Operator
  2606. is
  2607.  
  2608. DC88586F-6788-4678-A90C-4D79A8DE9BE4,Platform
  2609. Windows
  2610.  
  2611. DC9387EF-9B53-4C8B-AF18-5FDDAD31BD0E,Active
  2612. Yes
  2613.  
  2614. DC9387EF-9B53-4C8B-AF18-5FDDAD31BD0E,Alias
  2615. {}
  2616.  
  2617. DC9387EF-9B53-4C8B-AF18-5FDDAD31BD0E,Comment
  2618. {}
  2619.  
  2620. DC9387EF-9B53-4C8B-AF18-5FDDAD31BD0E,Components
  2621. 25A03054-7BF5-4B4A-A5E8-98C36C53A0F9
  2622.  
  2623. DC9387EF-9B53-4C8B-AF18-5FDDAD31BD0E,Description,subst
  2624. 1
  2625.  
  2626. DC9387EF-9B53-4C8B-AF18-5FDDAD31BD0E,ID
  2627. {}
  2628.  
  2629. DC9387EF-9B53-4C8B-AF18-5FDDAD31BD0E,Name
  2630. Typical
  2631.  
  2632. DCE54AB7-C9B6-4B3B-8FAC-C3D332B634CD,Active
  2633. Yes
  2634.  
  2635. DCE54AB7-C9B6-4B3B-8FAC-C3D332B634CD,Alias
  2636. {}
  2637.  
  2638. DCE54AB7-C9B6-4B3B-8FAC-C3D332B634CD,CheckCondition
  2639. {Before Pane is Displayed}
  2640.  
  2641. DCE54AB7-C9B6-4B3B-8FAC-C3D332B634CD,Comment
  2642. {}
  2643.  
  2644. DCE54AB7-C9B6-4B3B-8FAC-C3D332B634CD,Component
  2645. {}
  2646.  
  2647. DCE54AB7-C9B6-4B3B-8FAC-C3D332B634CD,FailureMessage
  2648. {}
  2649.  
  2650. DCE54AB7-C9B6-4B3B-8FAC-C3D332B634CD,ID
  2651. {}
  2652.  
  2653. DCE54AB7-C9B6-4B3B-8FAC-C3D332B634CD,Operator
  2654. is
  2655.  
  2656. DCE54AB7-C9B6-4B3B-8FAC-C3D332B634CD,Platform
  2657. Windows
  2658.  
  2659. E4876404-6179-4839-B6F0-0CE2C46F3AC0,Active
  2660. Yes
  2661.  
  2662. E4876404-6179-4839-B6F0-0CE2C46F3AC0,Alias
  2663. {}
  2664.  
  2665. E4876404-6179-4839-B6F0-0CE2C46F3AC0,Comment
  2666. {}
  2667.  
  2668. E4876404-6179-4839-B6F0-0CE2C46F3AC0,Component
  2669. {}
  2670.  
  2671. E4876404-6179-4839-B6F0-0CE2C46F3AC0,Conditions
  2672. {}
  2673.  
  2674. E4876404-6179-4839-B6F0-0CE2C46F3AC0,ExecuteAction
  2675. {After Pane is Displayed}
  2676.  
  2677. E4876404-6179-4839-B6F0-0CE2C46F3AC0,ExitType
  2678. Finish
  2679.  
  2680. E4876404-6179-4839-B6F0-0CE2C46F3AC0,ID
  2681. {}
  2682.  
  2683. E4876404-6179-4839-B6F0-0CE2C46F3AC0,IgnoreErrors
  2684. No
  2685.  
  2686. EBE76197-B5AB-4228-BA51-F7780EFD5C07,Active
  2687. Yes
  2688.  
  2689. EBE76197-B5AB-4228-BA51-F7780EFD5C07,Alias
  2690. {}
  2691.  
  2692. EBE76197-B5AB-4228-BA51-F7780EFD5C07,Comment
  2693. {}
  2694.  
  2695. EBE76197-B5AB-4228-BA51-F7780EFD5C07,Component
  2696. {}
  2697.  
  2698. EBE76197-B5AB-4228-BA51-F7780EFD5C07,Conditions
  2699. {2 conditions}
  2700.  
  2701. EBE76197-B5AB-4228-BA51-F7780EFD5C07,ExecuteAction
  2702. {After Pane is Displayed}
  2703.  
  2704. EBE76197-B5AB-4228-BA51-F7780EFD5C07,ID
  2705. {}
  2706.  
  2707. EBE76197-B5AB-4228-BA51-F7780EFD5C07,IgnoreErrors
  2708. No
  2709.  
  2710. EBE76197-B5AB-4228-BA51-F7780EFD5C07,State
  2711. disabled
  2712.  
  2713. EBE76197-B5AB-4228-BA51-F7780EFD5C07,Text
  2714. {}
  2715.  
  2716. EBE76197-B5AB-4228-BA51-F7780EFD5C07,Widget
  2717. NextButton
  2718.  
  2719. EE3898B7-7F54-4743-87F2-FCBF21BBC5C8,Active
  2720. Yes
  2721.  
  2722. EE3898B7-7F54-4743-87F2-FCBF21BBC5C8,Alias
  2723. {}
  2724.  
  2725. EE3898B7-7F54-4743-87F2-FCBF21BBC5C8,Comment
  2726. {}
  2727.  
  2728. EE3898B7-7F54-4743-87F2-FCBF21BBC5C8,Component
  2729. {}
  2730.  
  2731. EE3898B7-7F54-4743-87F2-FCBF21BBC5C8,Conditions
  2732. {}
  2733.  
  2734. EE3898B7-7F54-4743-87F2-FCBF21BBC5C8,ExecuteAction
  2735. {After Pane is Displayed}
  2736.  
  2737. EE3898B7-7F54-4743-87F2-FCBF21BBC5C8,ID
  2738. {}
  2739.  
  2740. EE3898B7-7F54-4743-87F2-FCBF21BBC5C8,IgnoreErrors
  2741. No
  2742.  
  2743. F56B3A55-F558-4D2C-ADFF-8B8B2C02E40F,Active
  2744. Yes
  2745.  
  2746. F56B3A55-F558-4D2C-ADFF-8B8B2C02E40F,Alias
  2747. {}
  2748.  
  2749. F56B3A55-F558-4D2C-ADFF-8B8B2C02E40F,CheckCondition
  2750. {Before Pane is Displayed}
  2751.  
  2752. F56B3A55-F558-4D2C-ADFF-8B8B2C02E40F,Comment
  2753. {}
  2754.  
  2755. F56B3A55-F558-4D2C-ADFF-8B8B2C02E40F,Component
  2756. {}
  2757.  
  2758. F56B3A55-F558-4D2C-ADFF-8B8B2C02E40F,FailureMessage
  2759. {}
  2760.  
  2761. F56B3A55-F558-4D2C-ADFF-8B8B2C02E40F,Filename
  2762. <%ProgramReadme%>
  2763.  
  2764. F56B3A55-F558-4D2C-ADFF-8B8B2C02E40F,ID
  2765. {}
  2766.  
  2767. F56B3A55-F558-4D2C-ADFF-8B8B2C02E40F,Operator
  2768. exists
  2769.  
  2770. FB0A7015-A12E-4BF1-8044-9D46E9512987,Active
  2771. Yes
  2772.  
  2773. FB0A7015-A12E-4BF1-8044-9D46E9512987,Alias
  2774. {}
  2775.  
  2776. FB0A7015-A12E-4BF1-8044-9D46E9512987,CheckCondition
  2777. {Before Pane is Displayed}
  2778.  
  2779. FB0A7015-A12E-4BF1-8044-9D46E9512987,Comment
  2780. {}
  2781.  
  2782. FB0A7015-A12E-4BF1-8044-9D46E9512987,Component
  2783. {}
  2784.  
  2785. FB0A7015-A12E-4BF1-8044-9D46E9512987,FailureMessage
  2786. {}
  2787.  
  2788. FB0A7015-A12E-4BF1-8044-9D46E9512987,ID
  2789. {}
  2790.  
  2791. FB0A7015-A12E-4BF1-8044-9D46E9512987,Operator
  2792. false
  2793.  
  2794. FB0A7015-A12E-4BF1-8044-9D46E9512987,String
  2795. <%InstallStopped%>
  2796.  
  2797. Linux-x86,Active
  2798. No
  2799.  
  2800. Linux-x86,BuildType
  2801. dynamic
  2802.  
  2803. Linux-x86,DefaultDirectoryPermission
  2804. 00755
  2805.  
  2806. Linux-x86,DefaultFilePermission
  2807. 00755
  2808.  
  2809. Linux-x86,Executable
  2810. <%AppName%>-<%Version%>-<%Platform%>-Install<%Ext%>
  2811.  
  2812. Linux-x86,InstallDir
  2813. <%Home%>/<%ShortAppName%>
  2814.  
  2815. Linux-x86,InstallType
  2816. Typical
  2817.  
  2818. Linux-x86,ProgramExecutable
  2819. <%InstallDir%>/CompleteCalc
  2820.  
  2821. Linux-x86,ProgramFolderAllUsers
  2822. No
  2823.  
  2824. Linux-x86,ProgramFolderName
  2825. <%AppName%>
  2826.  
  2827. Linux-x86,ProgramLicense
  2828. <%InstallDir%>/LICENSE.txt
  2829.  
  2830. Linux-x86,ProgramName
  2831. {}
  2832.  
  2833. Linux-x86,ProgramReadme
  2834. <%InstallDir%>/README.txt
  2835.  
  2836. Linux-x86,RequireRoot
  2837. No
  2838.  
  2839. Linux-x86,RootInstallDir
  2840. /usr/local/<%ShortAppName%>
  2841.  
  2842. Windows,Active
  2843. Yes
  2844.  
  2845. Windows,BuildType
  2846. {}
  2847.  
  2848. Windows,Executable
  2849. <%AppName%>-<%Version%>-Setup<%Ext%>
  2850.  
  2851. Windows,IncludeTWAPI
  2852. No
  2853.  
  2854. Windows,InstallDir
  2855. <%PROGRAM_FILES%>/<%AppName%>
  2856.  
  2857. Windows,InstallType
  2858. Typical
  2859.  
  2860. Windows,ProgramExecutable
  2861. <%InstallDir%>/CompleteCalc.exe
  2862.  
  2863. Windows,ProgramFolderAllUsers
  2864. No
  2865.  
  2866. Windows,ProgramFolderName
  2867. <%AppName%>
  2868.  
  2869. Windows,ProgramLicense
  2870. <%InstallDir%>/LICENSE.txt
  2871.  
  2872. Windows,ProgramName
  2873. {}
  2874.  
  2875. Windows,ProgramReadme
  2876. <%InstallDir%>/README.txt
  2877.  
  2878. Windows,WindowsIcon
  2879. {Setup Blue Screen.ico}
  2880.  
  2881. }
  2882.  
  2883. array set ::InstallJammer::files {files.tcl {proc ::InstallJammer::InitFiles {} {
  2884.     File ::587BACB0-66F3-4357-A3D5-4FC492A0D68D -name {Complete Calc} -parent BC9DDC29-8CDB-4C1E-A9F2-F002B44B6E20 -type dir -directory <%InstallDir%> -mtime 1167339232 -filemethod "Update files with more recent dates"
  2885.     File ::0BA90803-0E15-424F-8801-3755F9EEAE8E -name CompleteCalc.exe -parent BC9DDC29-8CDB-4C1E-A9F2-F002B44B6E20 -directory <%InstallDir%> -size 114688 -mtime 1167338442 -filemethod "Update files with more recent dates"
  2886.     File ::93C36D6C-F13C-4D71-B3A5-4B573CB91642 -name LICENSE.txt -parent BC9DDC29-8CDB-4C1E-A9F2-F002B44B6E20 -directory <%InstallDir%> -size 3295 -mtime 1155563416 -filemethod "Update files with more recent dates"
  2887.  
  2888. }} console.tcl ##\ \$Id\$\n##\n##\ Copyright\ (C)\ 2002\ \ Damon\ Courtney\n##\ \n##\ This\ program\ is\ free\ software\;\ you\ can\ redistribute\ it\ and/or\n##\ modify\ it\ under\ the\ terms\ of\ the\ GNU\ General\ Public\ License\n##\ as\ published\ by\ the\ Free\ Software\ Foundation\;\ either\ version\ 2\n##\ of\ the\ License,\ or\ (at\ your\ option)\ any\ later\ version.\n##\ \n##\ This\ program\ is\ distributed\ in\ the\ hope\ that\ it\ will\ be\ useful,\n##\ but\ WITHOUT\ ANY\ WARRANTY\;\ without\ even\ the\ implied\ warranty\ of\n##\ MERCHANTABILITY\ or\ FITNESS\ FOR\ A\ PARTICULAR\ PURPOSE.\ \ See\ the\n##\ GNU\ General\ Public\ License\ for\ more\ details.\n##\ \n##\ You\ should\ have\ received\ a\ copy\ of\ the\ GNU\ General\ Public\ License\n##\ along\ with\ this\ program\;\ if\ not,\ write\ to\ the\n##\ \ \ \ \ Free\ Software\ Foundation,\ Inc.\n##\ \ \ \ \ 51\ Franklin\ Street,\ Fifth\ Floor\n##\ \ \ \ \ Boston,\ MA\ \ 02110-1301,\ USA.\n##\n\nif\ \{!\[info\ exists\ tk_patchLevel\]\}\ \{\ return\ \}\n\nset\ consoleInterp\ \[interp\ create\]\n\$consoleInterp\ eval\ \[list\ set\ tk_library\ \$tk_library\]\n\$consoleInterp\ alias\ exit\ exit\nload\ \"\"\ Tk\ \$consoleInterp\n\n#\ 2.\ A\ command\ 'console'\ in\ the\ application\ interpreter\n\;proc\ console\ \{\ sub\ \{optarg\ \{\}\}\ \}\ \[subst\ -nocommands\ \{\n\ \ \ \ switch\ -exact\ --\ \\\$sub\ \{\n\ \ \ \ \ \ \ title\ \{\n\t\ \ \ \$consoleInterp\ eval\ wm\ title\ .\ \[list\ \\\$optarg\]\n\ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ hide\ \{\n\t\ \ \ \$consoleInterp\ eval\ wm\ withdraw\ .\n\ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ show\ \{\n\t\ \ \ \$consoleInterp\ eval\ wm\ deiconify\ .\n\ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ eval\ \{\n\t\ \ \ \$consoleInterp\ eval\ \\\$optarg\n\ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ default\ \{\n\t\ \ \ error\ \"bad\ option\ \\\\\\\"\\\$sub\\\\\\\":\ should\ be\ hide,\ show,\ or\ title\"\n\ \ \ \ \ \ \ \}\n\ \ \ \}\n\}\]\n\n#\ 3.\ Alias\ a\ command\ 'consoleinterp'\ in\ the\ console\ window\ interpreter\n#\ \ \ \ \ \ \ to\ cause\ evaluation\ of\ the\ command\ 'consoleinterp'\ in\ the\n#\ \ \ \ \ \ \ application\ interpreter.\n\;proc\ consoleinterp\ \{sub\ cmd\}\ \{\n\ \ \ switch\ -exact\ --\ \$sub\ \{\n\ \ \ \ \ \ \ eval\ \{\n\t\ \ \ uplevel\ #0\ \$cmd\n\ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ record\ \{\n\t\ \ \ history\ add\ \$cmd\n\t\ \ \ catch\ \{uplevel\ #0\ \$cmd\}\ retval\n\t\ \ \ return\ \$retval\n\ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ default\ \{\n\t\ \ \ error\ \"bad\ option\ \\\"\$sub\\\":\ should\ be\ eval\ or\ record\"\n\ \ \ \ \ \ \ \}\n\ \ \ \}\n\}\nif\ \{\[package\ vsatisfies\ \[package\ provide\ Tk\]\ 4\]\}\ \{\n\ \ \ \$consoleInterp\ alias\ interp\ consoleinterp\n\}\ else\ \{\n\ \ \ \$consoleInterp\ alias\ consoleinterp\ consoleinterp\n\}\n\n#\ 4.\ Bind\ the\ <Destroy>\ event\ of\ the\ application\ interpreter's\ main\n#\ \ \ \ window\ to\ kill\ the\ console\ (via\ tkConsoleExit)\nbind\ .\ <Destroy>\ \[list\ +if\ \{\[string\ match\ .\ %W\]\}\ \[list\ catch\ \\\n\ \ \ \ \ \ \ \[list\ \$consoleInterp\ eval\ tkConsoleExit\]\]\]\n\n#\ 5.\ Redefine\ the\ Tcl\ command\ 'puts'\ in\ the\ application\ interpreter\n#\ \ \ \ so\ that\ messages\ to\ stdout\ and\ stderr\ appear\ in\ the\ console.\nrename\ puts\ tcl_puts\n\;proc\ puts\ \{args\}\ \[subst\ -nocommands\ \{\n\ \ \ switch\ -exact\ --\ \[llength\ \\\$args\]\ \{\n\ \ \ \ \ \ \ 1\ \{\n\t\ \ \ if\ \{\[string\ match\ -nonewline\ \\\$args\]\}\ \{\n\t\ \ \ \ \ \ \ if\ \{\[catch\ \{uplevel\ 1\ \[linsert\ \\\$args\ 0\ tcl_puts\]\}\ msg\]\}\ \{\n\t\t\ \ \ regsub\ -all\ tcl_puts\ \\\$msg\ puts\ msg\n\t\t\ \ \ return\ -code\ error\ \\\$msg\n\t\ \ \ \ \ \ \ \}\n\t\ \ \ \}\ else\ \{\n\t\ \ \ \ \ \ \ \$consoleInterp\ eval\ \[list\ tkConsoleOutput\ stdout\ \\\n\t\t\ \ \ \ \ \ \ \"\[lindex\ \\\$args\ 0\]\\n\"\]\n\t\ \ \ \}\n\ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ 2\ \{\n\t\ \ \ if\ \{\[string\ match\ -nonewline\ \[lindex\ \\\$args\ 0\]\]\}\ \{\n\t\ \ \ \ \ \ \ \$consoleInterp\ eval\ \[list\ tkConsoleOutput\ stdout\ \\\n\t\t\ \ \ \ \ \ \ \[lindex\ \\\$args\ 1\]\]\n\t\ \ \ \}\ elseif\ \{\[string\ match\ stdout\ \[lindex\ \\\$args\ 0\]\]\}\ \{\n\t\ \ \ \ \ \ \ \$consoleInterp\ eval\ \[list\ tkConsoleOutput\ stdout\ \\\n\t\t\ \ \ \ \ \ \ \"\[lindex\ \\\$args\ 1\]\\n\"\]\n\t\ \ \ \}\ elseif\ \{\[string\ match\ stderr\ \[lindex\ \\\$args\ 0\]\]\}\ \{\n\t\ \ \ \ \ \ \ \$consoleInterp\ eval\ \[list\ tkConsoleOutput\ stderr\ \\\n\t\t\ \ \ \ \ \ \ \"\[lindex\ \\\$args\ 1\]\\n\"\]\n\t\ \ \ \}\ else\ \{\n\t\ \ \ \ \ \ \ if\ \{\[catch\ \{uplevel\ 1\ \[linsert\ \\\$args\ 0\ tcl_puts\]\}\ msg\]\}\ \{\n\t\t\ \ \ regsub\ -all\ tcl_puts\ \\\$msg\ puts\ msg\n\t\t\ \ \ return\ -code\ error\ \\\$msg\n\t\ \ \ \ \ \ \ \}\n\t\ \ \ \}\n\ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ 3\ \{\n\t\ \ \ if\ \{!\[string\ match\ -nonewline\ \[lindex\ \\\$args\ 0\]\]\}\ \{\n\t\ \ \ \ \ \ \ if\ \{\[catch\ \{uplevel\ 1\ \[linsert\ \\\$args\ 0\ tcl_puts\]\}\ msg\]\}\ \{\n\t\t\ \ \ regsub\ -all\ tcl_puts\ \\\$msg\ puts\ msg\n\t\t\ \ \ return\ -code\ error\ \\\$msg\n\t\ \ \ \ \ \ \ \}\n\t\ \ \ \}\ elseif\ \{\[string\ match\ stdout\ \[lindex\ \\\$args\ 1\]\]\}\ \{\n\t\ \ \ \ \ \ \ \$consoleInterp\ eval\ \[list\ tkConsoleOutput\ stdout\ \\\n\t\t\ \ \ \ \ \ \ \[lindex\ \\\$args\ 2\]\]\n\t\ \ \ \}\ elseif\ \{\[string\ match\ stderr\ \[lindex\ \\\$args\ 1\]\]\}\ \{\n\t\ \ \ \ \ \ \ \$consoleInterp\ eval\ \[list\ tkConsoleOutput\ stderr\ \\\n\t\t\ \ \ \ \ \ \ \[lindex\ \\\$args\ 2\]\]\n\t\ \ \ \}\ else\ \{\n\t\ \ \ \ \ \ \ if\ \{\[catch\ \{uplevel\ 1\ \[linsert\ \\\$args\ 0\ tcl_puts\]\}\ msg\]\}\ \{\n\t\t\ \ \ regsub\ -all\ tcl_puts\ \\\$msg\ puts\ msg\n\t\t\ \ \ return\ -code\ error\ \\\$msg\n\t\ \ \ \ \ \ \ \}\n\t\ \ \ \}\n\ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ default\ \{\n\t\ \ \ if\ \{\[catch\ \{uplevel\ 1\ \[linsert\ \\\$args\ 0\ tcl_puts\]\}\ msg\]\}\ \{\n\t\ \ \ \ \ \ \ regsub\ -all\ tcl_puts\ \\\$msg\ puts\ msg\n\t\ \ \ \ \ \ \ return\ -code\ error\ \\\$msg\n\t\ \ \ \}\n\ \ \ \ \ \ \ \}\n\ \ \ \}\n\}\]\n\$consoleInterp\ alias\ puts\ puts\n\n#\ 6.\ No\ matter\ what\ Tk_Main\ says,\ insist\ that\ this\ is\ an\ interactive\ \ shell\nset\ tcl_interactive\ 1\n\n########################################################################\n#\ Evaluate\ the\ Tk\ library\ script\ console.tcl\ in\ the\ console\ interpreter\n########################################################################\n\$consoleInterp\ eval\ source\ \[list\ \[file\ join\ \$tk_library\ console.tcl\]\]\n\nconsole\ hide\n\n\$consoleInterp\ eval\ \{\n\ \ \ if\ \{!\[llength\ \[info\ commands\ tkConsoleExit\]\]\}\ \{\n\ \ \ \ \ \ \ tk::unsupported::ExposePrivateCommand\ tkConsoleExit\n\ \ \ \}\n\}\n\$consoleInterp\ eval\ \{\n\ \ \ if\ \{!\[llength\ \[info\ commands\ tkConsoleOutput\]\]\}\ \{\n\ \ \ \ \ \ \ tk::unsupported::ExposePrivateCommand\ tkConsoleOutput\n\ \ \ \}\n\}\nif\ \{\[string\ match\ 8.3.4\ \$tk_patchLevel\]\}\ \{\n\ \ \ #\ Workaround\ bug\ in\ first\ draft\ of\ the\ tkcon\ enhancments\n\ \ \ \$consoleInterp\ eval\ \{\n\ \ \ \ \ \ \ bind\ Console\ <Control-Key-v>\ \{\}\n\ \ \ \}\n\}\n#\ Restore\ normal\ \[puts\]\ if\ console\ widget\ goes\ away...\nproc\ Oc_RestorePuts\ \{slave\}\ \{\n\ \ \ \ rename\ puts\ \{\}\n\ \ \ \ rename\ tcl_puts\ puts\n\ \ \ \ interp\ delete\ \$slave\n\}\n\$consoleInterp\ alias\ Oc_RestorePuts\ Oc_RestorePuts\ \$consoleInterp\n\$consoleInterp\ eval\ \{\n\ \ \ \ bind\ Console\ <Destroy>\ +Oc_RestorePuts\n\}\n\nunset\ consoleInterp\n\nconsole\ title\ \"\[wm\ title\ .\]\ Console\" actions.tcl {namespace eval ::InstallJammer::actions {}
  2889. proc ::InstallJammer::actions::AddWidget {obj} {
  2890.     global info
  2891.  
  2892.     set id     [$obj id]
  2893.     set parent [$obj parent]
  2894.     set window [$parent window]
  2895.     set widget $window.[$obj name]
  2896.  
  2897.     if {![info exists ::InstallJammer]} {
  2898.         variable ::InstallJammer::UserWidgets
  2899.         if {[info exists UserWidgets($id)]} { return }
  2900.         set UserWidgets($id) $widget
  2901.     }
  2902.  
  2903.     $id window $widget
  2904.  
  2905.     $obj properties props
  2906.  
  2907.     set opts [list]
  2908.  
  2909.     set style T[string totitle $props(Type)]
  2910.  
  2911.     set value $props(Value)
  2912.     if {[string is true -strict $value]} {
  2913.         set value 1
  2914.     } elseif {[string is false -strict $value]} {
  2915.         set value 0
  2916.     }
  2917.  
  2918.     switch -- $props(Type) {
  2919.         "checkbutton" {
  2920.             set varopt -variable
  2921.             if {[string length $props(Checked)]} {
  2922.                 set varval 0
  2923.                 if {$props(Checked)} { set varval 1 } 
  2924.             }
  2925.         }
  2926.  
  2927.         "entry" {
  2928.             set varopt -textvariable
  2929.         }
  2930.  
  2931.         "radiobutton" {
  2932.             set varopt -variable
  2933.             lappend opts -value $value
  2934.  
  2935.             if {[string is true -strict $props(Checked)]} {
  2936.                 set varval $value
  2937.             }
  2938.         }
  2939.     }
  2940.  
  2941.     if {[info exists varopt] && [string length $props(VirtualText)]} {
  2942.         lappend opts $varopt ::info($props(VirtualText))
  2943.         if {[info exists varval]} {
  2944.             set ::info($props(VirtualText)) $varval
  2945.         }
  2946.     }
  2947.  
  2948.     ::InstallJammer::SetVirtualText $info(Language) $parent $id  [::InstallJammer::GetText $id Text -subst 0]
  2949.     $parent set $id,subst $props(Text,subst)
  2950.  
  2951.     if {$props(Background) ne "system"} {
  2952.         ::InstallJammer::NewStyle $id $style -background $props(Background)
  2953.         lappend opts -style $id
  2954.     }
  2955.  
  2956.     eval [list ttk::$props(Type) $widget] $opts
  2957.  
  2958.     place $widget -in $window -x $props(X) -y $props(Y)  -width $props(Width) -height $props(Height)
  2959.  
  2960.     $parent widget set $id -widget $widget
  2961.  
  2962.     ::InstallJammer::UpdateWidgets -widgets $id -step $parent
  2963. }
  2964.  
  2965. proc ::InstallJammer::actions::AddWindowsUninstallEntry {obj} {
  2966.     global conf
  2967.  
  2968.     if {!$conf(windows)} { return }
  2969.  
  2970.     $obj get RegistryKeyName appkey
  2971.  
  2972.     set properties {
  2973.         UninstallString
  2974.         QuietUninstallString
  2975.         DisplayName
  2976.         DisplayIcon
  2977.         DisplayVersion
  2978.         Comments
  2979.         Contact
  2980.         HelpLink
  2981.         HelpTelephone
  2982.         InstallDate
  2983.         InstallLocation
  2984.         InstallSource
  2985.         Publisher
  2986.         Readme
  2987.         URLInfoAbout
  2988.         URLUpdateInfo
  2989.     }
  2990.  
  2991.     eval $obj properties props [lsort $properties]
  2992.  
  2993.     set key {HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion}
  2994.     append key "\\Uninstall\\[::InstallJammer::SubstText $appkey]"
  2995.  
  2996.     ## Try to insert this first value.  If it fails, it's probably
  2997.     ## because we don't have permission to write to the Uninstall registry
  2998.     ## for the local machine.  We want to switch over and try to write to
  2999.     ## the current user's Uninstall registry instead.
  3000.     if {[catch { registry set $key NoModify 1 dword } error]} {
  3001.         set key {HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion}
  3002.         append key "\\Uninstall\\[::InstallJammer::SubstText $appkey]"
  3003.  
  3004.         registry set $key NoModify 1 dword
  3005.     }
  3006.  
  3007.     registry set $key NoRepair 1 dword
  3008.  
  3009.     foreach var [array names props] {
  3010.     registry set $key $var [::InstallJammer::SubstText $props($var)]
  3011.     }
  3012.  
  3013.     ::InstallJammer::LogRegistry $key
  3014. }
  3015.  
  3016. proc ::InstallJammer::actions::CreateInstallPanes {obj} {
  3017.     global info
  3018.  
  3019.     set parent      [$obj parent]
  3020.     set progressbar [$parent widget get ProgressBar]
  3021.     if {![string length $progressbar]} { set progressbar noop }
  3022.  
  3023.     set children [$info(InstallMode) children recursive]
  3024.     set total    [llength $children]
  3025.     foreach id $children {
  3026.         $progressbar configure -value [expr {[incr0 i] * 100 / $total}]
  3027.         update
  3028.         if {[$id ispane]} {
  3029.             $info(Wizard) createstep $id
  3030.         }
  3031.     }
  3032. }
  3033.  
  3034. proc ::InstallJammer::actions::ExecuteAction {obj} {
  3035.     set id [$obj id]
  3036.  
  3037.     if {[$obj get Action action] && [string length $action]} {
  3038.         $obj get EvaluateConditions eval
  3039.         return [::InstallJammer::ExecuteActions $action  -parent $id -conditions $eval]
  3040.     }
  3041. }
  3042.  
  3043. proc ::InstallJammer::actions::ExecuteExternalProgram {obj} {
  3044.     set id [$obj id]
  3045.  
  3046.     $obj properties props
  3047.  
  3048.     set widget [join $props(ProgressiveOutputWidget) ""]
  3049.     set widget [[$obj parent] widget get $widget]
  3050.  
  3051.     set resultVarName [::InstallJammer::SubstText $props(ResultVirtualText)]
  3052.     set statusVarName [::InstallJammer::SubstText $props(StatusVirtualText)]
  3053.  
  3054.     set resultVar result
  3055.     if {[string length $resultVarName]} { set resultVar ::info($resultVarName) }
  3056.  
  3057.     set statusVar status
  3058.     if {[string length $statusVarName]} { set statusVar ::info($statusVarName) }
  3059.  
  3060.     set $statusVar 0
  3061.     set $resultVar ""
  3062.  
  3063.     ::InstallJammer::UpdateWidgets -update 1
  3064.  
  3065.     set workdir [::InstallJammer::SubstText $props(WorkingDirectory)]
  3066.     if {[string length $workdir] && [file exists $workdir]} {
  3067.         set pwd [pwd]
  3068.         cd $workdir
  3069.     }
  3070.  
  3071.     if {$props(ShowProgressiveOutput)} {
  3072.         set cmd [::InstallJammer::SubstText $props(ProgramCommandLine)]
  3073.  
  3074.         proc ::ReadOutput${id} { fp statusVar resultVar widget } {
  3075.             set data [read $fp]
  3076.  
  3077.             if {[eof $fp]} {
  3078.                 set $statusVar [catch { close $fp }]
  3079.                 return
  3080.             }
  3081.  
  3082.             if {$::conf(windows)} {
  3083.                 ## For some reason, Windows wants to give us two
  3084.                 ## newlines for every one that is actually output.
  3085.                 set data [string map [list \n\n \n] $data]
  3086.             }
  3087.  
  3088.             append $resultVar $data
  3089.             if {[string length $widget] && [winfo class $widget] eq "Text"} {
  3090.                 set auto [expr {[lindex [$widget yview] 1] == 1}]
  3091.  
  3092.                 $widget configure -state normal
  3093.                 $widget insert end $data
  3094.                 $widget configure -state disabled
  3095.  
  3096.                 ## If the user is all the way at the bottom of the text,
  3097.                 ## we want to keep auto-scrolling to the bottom. 
  3098.                 if {$auto} { $widget yview moveto 1.0 }
  3099.  
  3100.                 update idletasks
  3101.             }
  3102.         }
  3103.  
  3104.         set cmd [::InstallJammer::SubstForPipe $props(ProgramCommandLine)]
  3105.  
  3106.         if {[catch { open "|$cmd" } fp]} {
  3107.             set $statusVar 1
  3108.             set $resultVar $fp
  3109.             ::InstallJammer::UpdateWidgets -updateidletasks 1
  3110.         } else {
  3111.             fconfigure $fp -buffering none -blocking 0
  3112.             fileevent $fp readable  [list ::ReadOutput${id} $fp $statusVar $resultVar $widget]
  3113.  
  3114.             if {$props(WaitForProgram)} { vwait $statusVar }
  3115.         }
  3116.     } else {
  3117.         set cmd [::InstallJammer::SubstForEval $props(ProgramCommandLine)]
  3118.  
  3119.         if {!$props(WaitForProgram)} { 
  3120.             set $statusVar [catch { eval exec $cmd & } $resultVar]
  3121.         } else {
  3122.             set $statusVar [catch { eval exec $cmd } $resultVar]
  3123.         }
  3124.  
  3125.         ::InstallJammer::UpdateWidgets -updateidletasks 1
  3126.     }
  3127.  
  3128.     if {[info exists pwd]} { cd $pwd }
  3129. }
  3130.  
  3131. proc ::InstallJammer::actions::Exit {obj} {
  3132.     global info
  3133.  
  3134.     if {[$obj get ExitType] eq "Cancel"} {
  3135.         set info(InstallCancelled) 1
  3136.     }
  3137.         
  3138.     ## Walk through a list of possible exit routines and
  3139.     ## choose the best one we have.
  3140.     foreach command [list ::Exit ::InstallJammer::exit ::exit] {
  3141.         if {[::InstallJammer::CommandExists $command]} {
  3142.             $command
  3143.         }
  3144.     }
  3145. }
  3146.  
  3147. proc ::InstallJammer::actions::InstallDesktopShortcut {obj} {
  3148.     global conf
  3149.  
  3150.     set allusers [$obj get InstallForAllUsers]
  3151.  
  3152.     if {$conf(windows)} {
  3153.         if {$allusers} {
  3154.             $obj set ShortcutDirectory <%COMMON_DESKTOP%>
  3155.         } else {
  3156.             $obj set ShortcutDirectory <%DESKTOP%>
  3157.         }
  3158.         ::InstallJammer::actions::InstallWindowsShortcut $obj
  3159.     } else {
  3160.         if {[::InstallJammer::HasKDEDesktop]} {
  3161.             $obj set ShortcutDirectory <%KDEDesktop%>
  3162.             ::InstallJammer::actions::InstallUNIXShortcut $obj
  3163.         }
  3164.  
  3165.         if {[::InstallJammer::HasGnomeDesktop]} {
  3166.             $obj set ShortcutDirectory <%GnomeDesktop%>
  3167.             ::InstallJammer::actions::InstallUNIXShortcut $obj
  3168.         }
  3169.     }
  3170. }
  3171.  
  3172. proc ::InstallJammer::actions::InstallSelectedFiles {obj} {
  3173.     global info
  3174.     global conf
  3175.  
  3176.     update
  3177.  
  3178.     if {$conf(testing)} { return }
  3179.  
  3180.     set setups [SetupTypes children]
  3181.  
  3182.     ## If we have no setup types, we have nothing to do.
  3183.     if {![llength $setups]} { return }
  3184.  
  3185.     set setuptype [::InstallJammer::FindObjByName $info(InstallType) $setups]
  3186.  
  3187.     if {$setuptype eq ""} {
  3188.         return -code error "Install Selected Files failed: could not find current Setup Type in list of available Setup Types"
  3189.     }
  3190.  
  3191.     set conf(stop)  [::InstallJammer::TmpDir .stop]
  3192.     set conf(pause) [::InstallJammer::TmpDir .pause]
  3193.  
  3194.     set id     [$obj id]
  3195.     set parent [$obj parent]
  3196.  
  3197.     set conf(InstallID) $parent
  3198.  
  3199.     set info(TotalSize) 0
  3200.  
  3201.     set info(Status) "<%InstallPrepareText%>"
  3202.  
  3203.     set info(FileBeingInstalled)  ""
  3204.     set info(GroupBeingInstalled) ""
  3205.  
  3206.     ::InstallJammer::UpdateWidgets -update 1
  3207.  
  3208.     set groups [list]
  3209.     foreach component [$setuptype get Components] {
  3210.         if {![$component active]} { continue }
  3211.  
  3212.         foreach filegroup [$component get FileGroups] {
  3213.         ## If we've already processed this file group,
  3214.             ## we don't need to do it again.
  3215.         if {[lsearch -exact $groups $filegroup] < 0} {
  3216.                 lappend groups $filegroup
  3217.                 iincr info(TotalSize) [$filegroup get Size]
  3218.  
  3219.                 foreach file [$filegroup children] {
  3220.                     if {![$file active]} { continue }
  3221.                     lappend files($filegroup) $file
  3222.                 }
  3223.             }
  3224.     }
  3225.     }
  3226.  
  3227.     if {![llength $groups]} {
  3228.         ## We didn't find any groups.  We're done.
  3229.         set info(InstallFinished) 1
  3230.         return
  3231.     }
  3232.  
  3233.     set conf(InstallLog) [file join $info(InstallDir) install.log]
  3234.  
  3235.     set unpackBin    [::installkit::base]
  3236.     set unpackInf    [::InstallJammer::BuildUnpackInfo $groups files]
  3237.     set unpackScript [::InstallJammer::BuildUnpack]
  3238.  
  3239.     ::InstallJammer::ReadPreviousInstall
  3240.  
  3241.     set info(Installing)     1
  3242.     set info(InstallStarted) 1
  3243.  
  3244.     set info(Status) "<%FileBeingInstalledText%>"
  3245.  
  3246.     if {[info exists ::tcl_platform(threaded)]} {
  3247.         set tid [installkit::newThread thread::wait]
  3248.         set conf(UnpackThread) $tid
  3249.         thread::send $tid [list namespace eval ::InstallJammer {}]
  3250.         thread::send $tid [list source $unpackInf]
  3251.         thread::send -async $tid [list source $unpackScript]
  3252.  
  3253.         thread::errorproc ::InstallJammer::HandleThreadError
  3254.     } else {
  3255.         set cmd "|[list $unpackBin] [list $unpackScript] -- [list $unpackInf]"
  3256.         set conf(UnpackBin) $unpackBin
  3257.         set conf(UnpackFp)  [open $cmd]
  3258.  
  3259.         fconfigure $conf(UnpackFp) -blocking 0
  3260.         fileevent  $conf(UnpackFp) readable  [list ::InstallJammer::ReadUnpack $parent]
  3261.     }
  3262.  
  3263.     vwait ::info(Installing)
  3264.  
  3265.     set info(Installing)      0
  3266.     set info(InstallFinished) 1
  3267.  
  3268.     if {$info(InstallStopped)} { return }
  3269.  
  3270.     ::InstallJammer::StoreInfo $info(InstallDir)
  3271.     ::InstallJammer::StoreInfo [::InstallJammer::InstallInfoDir]
  3272.  
  3273.     incr info(TotalSize) [::InstallJammer::InstallComponentsTotalSize]
  3274.  
  3275.     if {!$info(InstallStopped) && $conf(windows)} {
  3276.     ## Broadcast a message telling Windows that the environment
  3277.     ## has changed.  This forces any environment variables
  3278.     ## changed during installation to be updated in all running
  3279.     ## Windows applications.
  3280.     set info(Status) "<%UpdateRegistryText%>"
  3281.         ::InstallJammer::UpdateWidgets -update 1
  3282.  
  3283.     registry broadcast Environment
  3284.     }
  3285.  
  3286.     ## If we saved files for rollback, we need to clean them up now.
  3287.     ## If the install was stopped in the middle, we don't want to do
  3288.     ## anything.  The cleanup routines will take care of that.
  3289.     if {$conf(rollback) && $info(InstallStarted) && !$info(InstallStopped)} {
  3290.         set info(Status)  "<%CleanupInstallText%>"
  3291.  
  3292.         ::InstallJammer::UpdateWidgets -update 1
  3293.  
  3294.         if {[info exists conf(LOG)]} {
  3295.             foreach line $conf(LOG) {
  3296.                 if {[lindex $line 0] eq ":FILE"} {
  3297.                     set file [lindex $line 1]
  3298.                     set roll [::InstallJammer::RollbackName $file]
  3299.                     if {[file exists $roll]} { file delete -force $roll }
  3300.                 }
  3301.             }
  3302.         }
  3303.     }
  3304.  
  3305.     set info(FileBeingInstalled)  ""
  3306.     set info(GroupBeingInstalled) ""
  3307. }
  3308.  
  3309. proc ::InstallJammer::actions::InstallUNIXShortcut {obj} {
  3310.     $obj properties props
  3311.  
  3312.     set path [::InstallJammer::SubstText $props(ShortcutDirectory)]
  3313.     set file [::InstallJammer::SubstText [file join $path $props(ShortcutName)]]
  3314.     if {![string match *.desktop $file]} { append file .desktop }
  3315.  
  3316.     if {![file exists $path]} { file mkdir $path }
  3317.  
  3318.     set fp [open $file w]
  3319.     puts $fp {[Desktop Entry]}
  3320.     puts $fp "Name=[::InstallJammer::SubstText $props(ShortcutName)]"
  3321.     puts $fp "Type=[::InstallJammer::SubstText $props(ShortcutType)]"
  3322.     puts $fp "URL=[::InstallJammer::SubstText $props(TargetFileName)]"
  3323.     puts $fp "Exec='[::InstallJammer::SubstText $props(TargetFileName)]'"
  3324.     if {![lempty $props(IconPath)]}  {
  3325.         puts $fp "Icon=[::InstallJammer::SubstText $props(IconPath)]"
  3326.     }
  3327.  
  3328.     if {![lempty $props(AdditionalArguments)]} {
  3329.         puts $fp [::InstallJammer::SubstText $props(AdditionalArguments)]
  3330.     }
  3331.  
  3332.     close $fp
  3333.  
  3334.     close [open $file]
  3335.  
  3336.     ::InstallJammer::LogFile $file
  3337. }
  3338.  
  3339. proc ::InstallJammer::actions::InstallUninstaller {obj} {
  3340.     global info
  3341.     global conf
  3342.  
  3343.     set info(Status) [$obj get Message]
  3344.     ::InstallJammer::UpdateWidgets -update 1
  3345.  
  3346.     set uninstall    [::InstallJammer::TmpDir uninstall.tcl]
  3347.  
  3348.     $obj get UninstallDirectory directory
  3349.     set uninstallBin [file join $directory uninstall<%Ext%>]
  3350.     set uninstallBin [::InstallJammer::SubstText $uninstallBin]
  3351.  
  3352.     ::InstallJammer::CreateDir [file dirname $uninstallBin]
  3353.  
  3354.     set arrays [list info ::InstallJammer::Properties]
  3355.  
  3356.     set fp [open $uninstall w]
  3357.     puts $fp "namespace eval ::InstallJammer {}"
  3358.     
  3359.     foreach array $arrays {
  3360.         puts $fp "array set $array [list [array get $array]]"
  3361.     }
  3362.  
  3363.     foreach file [list common.tcl gui.tcl conditions.tcl uninstall.tcl] {
  3364.     puts $fp $::InstallJammer::files($file)
  3365.     }
  3366.     close $fp
  3367.  
  3368.     set opts [list -noinstall -o $uninstallBin -w [::installkit::base]]
  3369.  
  3370.     if {$conf(windows)} {
  3371.         set desc "Uninstall <%AppName%> <%Version%>"
  3372.         lappend opts -filedescription [::InstallJammer::SubstText $desc]
  3373.     }
  3374.  
  3375.     set catalog [file join $::installkit::root catalogs messages]
  3376.     file copy $catalog [::InstallJammer::TmpDir]
  3377.     lappend opts -catalog [::InstallJammer::TmpDir messages]
  3378.  
  3379.     ## Create the uninstall binary.
  3380.     eval ::InstallJammer::Wrap $opts [list $uninstall]
  3381.  
  3382.     ::InstallJammer::LogFile        $uninstallBin
  3383.     ::InstallJammer::SetVersionInfo $uninstallBin
  3384.     ::InstallJammer::SetPermissions $uninstallBin 00755
  3385.  
  3386.     set conf(uninstall)   $uninstallBin
  3387.     set info(Uninstaller) $uninstallBin
  3388.  
  3389.     return 1
  3390. }
  3391.  
  3392. proc ::InstallJammer::actions::InstallWindowsShortcut {obj} {
  3393.     global conf
  3394.  
  3395.     if {!$conf(windows)} { return }
  3396.  
  3397.     $obj properties props
  3398.  
  3399.     set target [::InstallJammer::SubstText $props(TargetFileName)]
  3400.  
  3401.     if {![string match "*://*" $target] && ![file exists $target]} { return }
  3402.  
  3403.     lappend list -objectpath $target
  3404.  
  3405.     if {![lempty $props(WorkingDirectory)]} {
  3406.     lappend list -workingdirectory
  3407.         lappend list [::InstallJammer::SubstText $props(WorkingDirectory)]
  3408.     }
  3409.  
  3410.     if {![lempty $props(IconPath)]} {
  3411.     lappend list -icon [::InstallJammer::SubstText $props(IconPath)]
  3412.         lappend list $props(IconPathIndex)
  3413.     }
  3414.  
  3415.     if {![lempty $props(CommandLineArguments)]} {
  3416.     lappend list -arguments
  3417.         lappend list [::InstallJammer::SubstText $props(CommandLineArguments)]
  3418.     }
  3419.  
  3420.     lappend list -showcommand $props(WindowState)
  3421.  
  3422.     set dir      [::InstallJammer::SubstText $props(ShortcutDirectory)]
  3423.     set linkPath [::InstallJammer::SubstText $props(ShortcutName)]
  3424.     set linkPath [file join $dir $linkPath]
  3425.     if {![string match *.lnk $linkPath]} { append linkPath .lnk }
  3426.  
  3427.     if {![file exists $dir]} { ::InstallJammer::CreateDir $dir }
  3428.  
  3429.     eval [list ::installkit::Windows::createShortcut $linkPath] $list
  3430.     ::InstallJammer::LogFile $linkPath
  3431. }
  3432.  
  3433. proc ::InstallJammer::actions::ModifyWidget {obj} {
  3434.     global info
  3435.  
  3436.     set parent [$obj parent]
  3437.  
  3438.     $obj properties props
  3439.  
  3440.     if {![string length $props(Widget)]} { return }
  3441.  
  3442.     set args [list]
  3443.     if {[string length $props(Text)]}  { lappend args -text $props(Text) }
  3444.     if {[string length $props(State)]} { lappend args -state $props(State) }
  3445.  
  3446.     if {![llength $args]} { return }
  3447.  
  3448.     foreach widget [split $props(Widget) \;] {
  3449.         set widget [join [string trim $widget] ""]
  3450.         switch -- $widget {
  3451.             "BackButton" - "NextButton" - "CancelButton" {
  3452.                 set widget [string tolower [string map {Button ""} $widget]]
  3453.                 eval [list $info(Wizard) itemconfigure $widget] $args
  3454.             }
  3455.  
  3456.             default {
  3457.                 set widget [$parent widget get $widget]
  3458.                 eval [list $widget configure] $args
  3459.             }
  3460.         }
  3461.     }
  3462.  
  3463.     update idletasks
  3464. }
  3465.  
  3466. proc ::InstallJammer::actions::MoveForward {obj} {
  3467.     global info
  3468.  
  3469.     set next [$info(Wizard) step next]
  3470.  
  3471.     ## If this is the last step, call the action to exit the install.
  3472.     if {![string length $next]} {
  3473.         ::InstallJammer::actions::Exit $obj
  3474.     } else {
  3475.         after 0 [list $info(Wizard) next 1]
  3476.     }
  3477. }
  3478.  
  3479. proc ::InstallJammer::actions::TextWindow {obj} {
  3480.     global info
  3481.  
  3482.     set wizard [::InstallJammer::Wizard]
  3483.  
  3484.     set id [$obj id]
  3485.  
  3486.     $id window .[$id name]
  3487.     set top [$id window]
  3488.  
  3489.     $obj properties props
  3490.  
  3491.     toplevel     $top
  3492.     wm withdraw  $top
  3493.     wm title     $top [::InstallJammer::GetText $id Title]
  3494.     wm transient $top [::InstallJammer::TransientParent]
  3495.     wm geometry  $top $props(Width)x$props(Height)
  3496.  
  3497.     grid rowconfigure    $top 1 -weight 1
  3498.     grid columnconfigure $top 0 -weight 1
  3499.  
  3500.     if {$props(GrabFocus)} {
  3501.         ::InstallJammer::Grab $top
  3502.         bind $top <Destroy> [list ::InstallJammer::Grab release $top]
  3503.     }
  3504.  
  3505.     ::InstallJammer::PlaceWindow $id -width $props(Width) -height $props(Height)
  3506.  
  3507.     if {[string length [::InstallJammer::GetText $id Caption]]} {
  3508.         label $top.caption -anchor w
  3509.         grid $top.caption -row 0 -column 0 -padx 5 -pady [list 5 10] -sticky w
  3510.         $id widget set Caption -widget $top.caption
  3511.     }
  3512.  
  3513.     text $top.message -bg white -bd 2 -relief sunken -wrap $props(TextWrap)  -yscrollcommand [list $top.vs set] -xscrollcommand [list $top.hs set]
  3514.     grid $top.message -row 1 -column 0 -padx [list 5 0] -sticky news
  3515.     $id widget set Message -widget $top.message
  3516.  
  3517.     ttk::scrollbar $top.vs -command [list $top.message yview]
  3518.     grid $top.vs -row 1 -column 1 -sticky ns -padx [list 0 5]
  3519.  
  3520.     ttk::scrollbar $top.hs -command [list $top.message xview] -orient horizontal
  3521.     grid $top.hs -row 2 -column 0 -sticky ew -padx [list 5 0] -pady [list 0 5]
  3522.  
  3523.     set width [string length [::InstallJammer::GetText $id CloseButton]]
  3524.     if {$width < 12} { set width 12 }
  3525.  
  3526.     ttk::button $top.close -width $width -command [list destroy $top]
  3527.     grid $top.close -row 3 -column 0 -padx 5 -pady 5 -sticky e -columnspan 2
  3528.     $id widget set CloseButton -widget $top.close
  3529.  
  3530.     set file [::InstallJammer::SubstText $props(TextFile)]
  3531.     if {[file exists $file]} {
  3532.         $id set Message,subst 0
  3533.         ::InstallJammer::SetVirtualText $info(Language)  $id Message [read_file $file]
  3534.     }
  3535.  
  3536.     ::InstallJammer::UpdateWidgets -step $id -updateidletasks 1
  3537.  
  3538.     focus $top.message
  3539.  
  3540.     wm deiconify $top
  3541.  
  3542.     if {$props(WaitOnWindow)} { tkwait window $top }
  3543. }
  3544.  
  3545. } gui.tcl {proc ::InitGui {} {
  3546.         if {[catch { package require Tk } error]} {
  3547.             puts "This program must be run in a graphical environment"
  3548.             puts "or in silent, unattended mode (with the -S option)."
  3549.             ::exit 1
  3550.         }
  3551.     wm withdraw .
  3552. array set ::images {F8912289-F9F6-4C2E-8058-C38BD7F3E27B,Icon {c:/program files/installjammer/images/modern/small/setupmodernsmall01.gif} 7F7C9C19-3650-4E50-8B27-32C9644DF62B,Icon {c:/program files/installjammer/images/modern/small/setupmodernsmall01.gif} E407FB36-48CE-4081-9051-6BAA771E761A,Image {c:/program files/installjammer/images/modern/setupmodern01.gif} A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3,Image {c:/program files/installjammer/images/modern/setupmodern01.gif} 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D,Icon {c:/program files/installjammer/images/modern/small/setupmodernsmall01.gif} 4C3FF654-9F5C-4679-B71D-F23E14F61844,Image {c:/program files/installjammer/images/modern/setupmodern01.gif} A2E136B8-114D-4028-876B-5F7DE6E5D06C,Image {c:/program files/installjammer/images/modern/setupmodern01.gif} 44F378EE-B695-45D5-96FE-1BBC93596B1F,Icon {c:/program files/installjammer/images/modern/small/setupmodernsmall01.gif} 39A03798-2744-48BB-8077-84B333E50E14,Icon {c:/program files/installjammer/images/modern/small/setupmodernsmall01.gif} 354BBA54-2679-44CC-B528-BB123868926D,Icon {c:/program files/installjammer/images/modern/small/setupmodernsmall01.gif} 26169907-3309-4C13-80BA-E6392EFA3702,Icon {c:/program files/installjammer/images/modern/small/setupmodernsmall01.gif}}
  3553. image create photo {c:/program files/installjammer/images/modern/small/setupmodernsmall01.gif} -data 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
  3554. image create photo {c:/program files/installjammer/images/modern/setupmodern01.gif} -data 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
  3555.  
  3556.  
  3557.  
  3558. package require Tcl 8.1.1
  3559.  
  3560. namespace eval Widget {
  3561. variable _class
  3562. variable _tk_widget
  3563.  
  3564. variable _theme 0
  3565.  
  3566. variable  _optiontype
  3567. array set _optiontype {
  3568. TkResource Widget::_test_tkresource
  3569. BwResource Widget::_test_bwresource
  3570. Enum       Widget::_test_enum
  3571. Int        Widget::_test_int
  3572. Boolean    Widget::_test_boolean
  3573. Boolean2   Widget::_test_boolean2
  3574. String     Widget::_test_string
  3575. Flag       Widget::_test_flag
  3576. Synonym    Widget::_test_synonym
  3577. Color      Widget::_test_color
  3578. Color2     Widget::_test_color2
  3579. Padding    Widget::_test_padding
  3580. }
  3581.  
  3582. proc use {} {}
  3583. }
  3584.  
  3585.  
  3586. proc Widget::CreateTempWidget { class {command frame} } {
  3587. set class [string map [list :: ""] $class]
  3588. set path  ".#BWidget.#Class#$class"
  3589. if {![winfo exists .#BWidget]} { frame .#BWidget }
  3590. if {![winfo exists $path]} {
  3591. if {[string equal $command "frame"]
  3592. || [string equal $command "toplevel"]} {
  3593. $command $path -class $class
  3594. if {[string equal $command "toplevel"]} { wm withdraw $path }
  3595. } else {
  3596. $command $path
  3597. }
  3598. }
  3599. return $path
  3600. }
  3601.  
  3602.  
  3603. proc Widget::tkinclude { class tkwidget subpath args } {
  3604. foreach {cmd lopt} $args {
  3605. switch -- $cmd {
  3606. remove {
  3607. foreach option $lopt {
  3608. set remove($option) 1
  3609. }
  3610. }
  3611.  
  3612. include {
  3613. foreach option $lopt {
  3614. set include($option) 1
  3615. }
  3616. }
  3617.  
  3618. prefix {
  3619. set prefix [lindex $lopt 0]
  3620. foreach option [lrange $lopt 1 end] {
  3621. set rename($option) "-$prefix[string range $option 1 end]"
  3622. }
  3623. }
  3624.  
  3625. rename - readonly - initialize {
  3626. array set $cmd $lopt
  3627. }
  3628.  
  3629. default {
  3630. return -code error "invalid argument \"$cmd\""
  3631. }
  3632. }
  3633. }
  3634.  
  3635. namespace eval $class {}
  3636. upvar 0 ${class}::opt classopt
  3637. upvar 0 ${class}::map classmap
  3638. upvar 0 ${class}::map$subpath submap
  3639. upvar 0 ${class}::optionExports exports
  3640. upvar 0 ${class}::subpaths subpaths
  3641.  
  3642. if {![info exists subpaths($subpath)]} { set subpaths($subpath) [list] }
  3643. eval [list lappend subpaths($subpath)] [array get initialize]
  3644.  
  3645. set widg [Widget::CreateTempWidget $tkwidget $tkwidget]
  3646. foreach optdesc [_get_tkwidget_options $tkwidget] {
  3647. set option [lindex $optdesc 0]
  3648.  
  3649. if {[info exists remove($option)]} { continue }
  3650. if {[info exists include] && ![info exists include($option)]} {continue}
  3651.  
  3652. if {[llength $optdesc] == 3} {
  3653. set syn [lindex $optdesc 1]
  3654. if {![info exists remove($syn)]} {
  3655. if {[info exists rename($syn)]} {
  3656. set classopt($option) [list Synonym $rename($syn)]
  3657. } else {
  3658. set classopt($option) [list Synonym $syn]
  3659. }
  3660. }
  3661.  
  3662. continue
  3663. }
  3664.  
  3665. set ro      0
  3666. set value   [lindex $optdesc 1]
  3667. set realopt $option
  3668.  
  3669. if {[info exists rename($option)]} {
  3670. set realopt $option
  3671. set option  $rename($option)
  3672. }
  3673.  
  3674. if {[info exists readonly($option)]} {
  3675. set ro $readonly($option)
  3676. }
  3677.  
  3678. set optionval [list $tkwidget $realopt]
  3679. set classopt($option) [list TkResource $value $ro $optionval]
  3680.  
  3681. if {![info exists initialize($option)]} {
  3682. set conf    [_configure_option $option ""]
  3683. set dbName  [lindex $conf 0]
  3684. set dbClass [lindex $conf 1]
  3685.  
  3686. set def [option get $widg $dbName $dbClass]
  3687. if {[string length $def]} {
  3688. set value $def
  3689. lappend subpaths($subpath) $option $value
  3690. }
  3691. }
  3692.  
  3693.  
  3694. lappend classmap($option) $subpath "" $realopt
  3695. set submap($realopt) $option
  3696. }
  3697. }
  3698.  
  3699.  
  3700. proc Widget::bwinclude { class subclass subpath args } {
  3701. upvar 0 ${subclass}::opt subclassopt
  3702.  
  3703. foreach {cmd lopt} $args {
  3704. switch -- $cmd {
  3705. remove {
  3706. foreach option $lopt {
  3707. set remove($option) 1
  3708. }
  3709. }
  3710.  
  3711. include {
  3712. foreach option $lopt {
  3713. set include($option) 1
  3714. }
  3715. }
  3716.  
  3717. prefix {
  3718. set prefix   [lindex $lopt 0]
  3719. set options  [lrange $lopt 1 end]
  3720. set doremove [string equal [lindex $options 0] "remove"]
  3721. if {![llength $options] || $doremove} {
  3722. set options  [list]
  3723. set toremove [lrange $options 1 end]
  3724. foreach option [array names subclassopt] {
  3725. if {[lsearch -exact $toremove $option] < 0} {
  3726. lappend options $option
  3727. }
  3728. }
  3729. }
  3730.  
  3731. foreach option $options {
  3732. set rename($option) "-$prefix[string range $option 1 end]"
  3733. }
  3734. }
  3735.  
  3736. rename - readonly - initialize {
  3737. array set $cmd $lopt
  3738. }
  3739.  
  3740. default {
  3741. return -code error "invalid argument \"$cmd\""
  3742. }
  3743. }
  3744. }
  3745.  
  3746. namespace eval $class {}
  3747. upvar 0 ${class}::opt classopt
  3748. upvar 0 ${class}::map classmap
  3749. upvar 0 ${class}::map$subpath submap
  3750. upvar 0 ${class}::optionExports exports
  3751. upvar 0 ${subclass}::optionExports subexports
  3752. upvar 0 ${class}::subpaths subpaths
  3753.  
  3754. if {![info exists subpaths($subpath)]} { set subpaths($subpath) [list] }
  3755. eval [list lappend subpaths($subpath)] [array get initialize]
  3756.  
  3757. set path [Widget::CreateTempWidget $class]
  3758. foreach {option optdesc} [array get subclassopt] {
  3759. set subOption $option
  3760.  
  3761. if {[info exists remove($option)]} { continue }
  3762. if {[info exists include] && ![info exists include($option)]} {continue}
  3763.  
  3764. set type [lindex $optdesc 0]
  3765. if {[string equal $type "Synonym"]} {
  3766. set syn [lindex $optdesc 1]
  3767. if {![info exists remove($syn)]} {
  3768. if {[info exists rename($syn)]} {
  3769. set classopt($option) [list Synonym $rename($syn)]
  3770. } else {
  3771. set classopt($option) [list Synonym $syn]
  3772. }
  3773. }
  3774. continue
  3775. }
  3776.  
  3777. set ro      [lindex $optdesc 2]
  3778. set value   [lindex $optdesc 1]
  3779. set realopt $option
  3780.  
  3781. if {[info exists rename($option)]} {
  3782. set realopt $option
  3783. set option  $rename($option)
  3784. }
  3785.  
  3786. if {[info exists initialize($option)]} {
  3787. set value $initialize($option)
  3788. }
  3789.  
  3790. if {[info exists readonly($option)]} {
  3791. set ro $readonly($option)
  3792. }
  3793.  
  3794. if {![info exists initialize($option)]} {
  3795. set conf    [_configure_option $option ""]
  3796. set dbName  [lindex $conf 0]
  3797. set dbClass [lindex $conf 1]
  3798.  
  3799. set def [option get $path $dbName $dbClass]
  3800. if {[string length $def]} {
  3801. set value $def
  3802. lappend subpaths($subpath) $option $value
  3803. }
  3804. }
  3805.  
  3806. set classopt($option) [list $type $value $ro [lindex $optdesc 3]]
  3807.  
  3808.  
  3809. lappend classmap($option) $subpath $subclass $realopt
  3810. set submap($realopt) $option
  3811. }
  3812. }
  3813.  
  3814.  
  3815. proc Widget::declare { class optlist } {
  3816. variable _optiontype
  3817.  
  3818. namespace eval $class {}
  3819. upvar 0 ${class}::opt classopt
  3820. upvar 0 ${class}::optionExports exports
  3821. upvar 0 ${class}::optionClass optionClass
  3822.  
  3823. set path [Widget::CreateTempWidget $class]
  3824. foreach optdesc $optlist {
  3825. set option  [lindex $optdesc 0]
  3826. set optdesc [lrange $optdesc 1 end]
  3827. set type    [lindex $optdesc 0]
  3828.  
  3829. if {![info exists _optiontype($type)]} {
  3830. return -code error "invalid option type \"$type\""
  3831. }
  3832.  
  3833. if {[string equal $type "Synonym"]} {
  3834. set syn [lindex $optdesc 1]
  3835. if {![info exists classopt($syn)]} {
  3836. return -code error  "unknow option \"$syn\" for Synonym \"$option\""
  3837. }
  3838. set classopt($option) [list Synonym $syn]
  3839. continue
  3840. }
  3841.  
  3842. set value [lindex $optdesc 1]
  3843. set ro    [lindex $optdesc 2]
  3844. set arg   [lindex $optdesc 3]
  3845.  
  3846. set conf    [_configure_option $option ""]
  3847. set dbName  [lindex $conf 0]
  3848. set dbClass [lindex $conf 1]
  3849. set default [option get $path $dbName $dbClass]
  3850.  
  3851. if {[string equal $type "BwResource"]} {
  3852. set subclass    [lindex $arg 0]
  3853. set realopt     [lindex $arg 1]
  3854. if {![string length $realopt]} { set realopt $option }
  3855.  
  3856. upvar 0 ${subclass}::opt subclassopt
  3857. if {![info exists subclassopt($realopt)]} {
  3858. return -code error "unknow option \"$realopt\""
  3859. }
  3860.  
  3861. set suboptdesc $subclassopt($realopt)
  3862. if {![string length $value]} {
  3863. set value [lindex $suboptdesc 1]
  3864. }
  3865.  
  3866. set type [lindex $suboptdesc 0]
  3867. set ro   [lindex $suboptdesc 2]
  3868. set arg  [lindex $suboptdesc 3]
  3869. set classopt($option) [list $type $value $ro $arg]
  3870. continue
  3871. }
  3872.  
  3873. if {[string equal $type "TkResource"]} {
  3874. set tkwidget [lindex $arg 0]
  3875. set widg [Widget::CreateTempWidget $tkwidget $tkwidget]
  3876. set realopt  [lindex $arg 1]
  3877. if { ![string length $realopt] } {
  3878. set realopt $option
  3879. }
  3880. set tkoptions [_get_tkwidget_options $tkwidget]
  3881. if {![string length $value]} {
  3882. set ind [lsearch $tkoptions [list $realopt *]]
  3883. set value [lindex [lindex $tkoptions $ind] end]
  3884. }
  3885. set classopt($option) [list TkResource $value $ro  [list $tkwidget $realopt]]
  3886. set optionClass($option) [lindex [$widg configure $realopt] 1]
  3887. continue
  3888. }
  3889.  
  3890. if {[string equal $type "Color"]} {
  3891. if {[info exists ::BWidget::colors($value)]} {
  3892. set value $::BWidget::colors($value)
  3893. }
  3894. }
  3895.  
  3896.  
  3897. set classopt($option) [list $type $value $ro $arg]
  3898. }
  3899. }
  3900.  
  3901.  
  3902. proc Widget::define { class filename args } {
  3903. variable _inuse
  3904. variable ::BWidget::use
  3905.  
  3906. proc ::${class}::use {} {}
  3907.  
  3908. if {[set x [lsearch -exact $args "-classonly"]] > -1} {
  3909. set args [lreplace $args $x $x]
  3910. } else {
  3911. interp alias {} ::${class} {} ${class}::create
  3912.  
  3913. proc ::${class}::cget { path option } {
  3914. return [Widget::cget $path $option]
  3915. }
  3916.  
  3917. proc ::${class}::configure { path args } {
  3918. return [Widget::configure $path $args]
  3919. }
  3920.  
  3921. bind $class <Destroy> [list Widget::destroy %W]
  3922. }
  3923.  
  3924. set _inuse($class) 0
  3925.  
  3926. set use($class)      $args
  3927. set use($class,file) $filename
  3928. lappend use(classes) $class
  3929.  
  3930. foreach class $args { ${class}::use }
  3931. }
  3932.  
  3933.  
  3934. proc Widget::create { class path {rename 1} } {
  3935. if {$rename} { rename $path ::$path:cmd }
  3936. set cmd "${class}::\$cmd"
  3937. proc ::$path { cmd args }  [subst {return \[eval \[linsert \$args 0 $cmd [list $path]\]\]}]
  3938. return $path
  3939. }
  3940.  
  3941.  
  3942. proc Widget::addmap { class subclass subpath options } {
  3943. upvar 0 ${class}::opt classopt
  3944. upvar 0 ${class}::optionExports exports
  3945. upvar 0 ${class}::optionClass optionClass
  3946. upvar 0 ${class}::map classmap
  3947. upvar 0 ${class}::map$subpath submap
  3948. upvar 0 ${class}::subpaths subpaths
  3949.  
  3950. if {![info exists subpaths($subpath)]} { set subpaths($subpath) [list] }
  3951.  
  3952. foreach {option realopt} $options {
  3953. if {![string length $realopt]} { set realopt $option }
  3954.  
  3955.  
  3956. lappend classmap($option) $subpath $subclass $realopt
  3957. set submap($realopt) $option
  3958.  
  3959. lappend subpaths($subpath) $realopt [lindex $classopt($option) 1]
  3960. }
  3961. }
  3962.  
  3963.  
  3964. proc Widget::syncoptions { class subclass subpath options } {
  3965. upvar 0 ${class}::sync classync
  3966. upvar 0 ${class}::subpaths subpaths
  3967.  
  3968. if {![info exists subpaths($subpath)]} { set subpaths($subpath) [list] }
  3969.  
  3970. foreach {option realopt} $options {
  3971. if {![string length $realopt]} { set realopt $option }
  3972. set classync($option) [list $subpath $subclass $realopt]
  3973. }
  3974. }
  3975.  
  3976.  
  3977. proc Widget::init { class path options {initFromODB 0} } {
  3978. variable _inuse
  3979.  
  3980. upvar 0 Widget::_optiontype opttype
  3981. upvar 0 ${class}::opt classopt
  3982. upvar 0 ${class}::map classmap
  3983. upvar 0 ${class}::$path:opt  pathopt
  3984. upvar 0 ${class}::$path:mod  pathmod
  3985. upvar 0 ${class}::$path:init pathinit
  3986.  
  3987. if {[info exists pathopt]} { unset pathopt }
  3988. if {[info exists pathmod]} { unset pathmod }
  3989.  
  3990. set fpath    $path
  3991. set rdbclass [string map [list :: ""] $class]
  3992. if {![winfo exists $path]} { set fpath [Widget::CreateTempWidget $class] }
  3993.  
  3994. foreach {option optdesc} [array get classopt] {
  3995. set pathmod($option) 0
  3996. if {[info exists classmap($option)]} { continue }
  3997.  
  3998. set type [lindex $optdesc 0]
  3999. if {[string equal $type "Synonym"]} { continue }
  4000.  
  4001. set alt ""
  4002. if {[string equal $type "TkResource"]} {
  4003. set alt [lindex [lindex $optdesc 3] 1]
  4004. }
  4005.  
  4006. set optdb [lindex [_configure_option $option $alt] 0]
  4007. set def   [option get $fpath $optdb $rdbclass]
  4008. if {[string length $def]} {
  4009. set pathopt($option) $def
  4010. } else {
  4011. set pathopt($option) [lindex $optdesc 1]
  4012. }
  4013. }
  4014.  
  4015. if {![info exists _inuse($class)]} { set _inuse($class) 0 }
  4016. incr _inuse($class)
  4017.  
  4018. set Widget::_class($path) $class
  4019.  
  4020. if {$initFromODB} {
  4021. array set pathopt $options
  4022. } else {
  4023. foreach {option value} $options {
  4024. if {![info exists classopt($option)]} {
  4025. unset pathopt
  4026. unset pathmod
  4027. return -code error "unknown option \"$option\""
  4028. }
  4029.  
  4030. set optdesc $classopt($option)
  4031. set type    [lindex $optdesc 0]
  4032. if {[string equal $type "Synonym"]} {
  4033. set option  [lindex $optdesc 1]
  4034. set optdesc $classopt($option)
  4035. set type    [lindex $optdesc 0]
  4036. }
  4037.  
  4038. set arg [lindex $optdesc 3]
  4039. set pathopt($option)  [$opttype($type) $option $value $arg]
  4040. set pathinit($option) $pathopt($option)
  4041. }
  4042. }
  4043. }
  4044.  
  4045.  
  4046.  
  4047. proc Widget::initFromODB { class path options } {
  4048. Widget::init $class $path $options 1
  4049. }
  4050.  
  4051.  
  4052.  
  4053.  
  4054. proc Widget::copyinit { class templatepath path options } {
  4055. upvar 0 ${class}::opt classopt  ${class}::$path:opt     pathopt  ${class}::$path:mod     pathmod  ${class}::$path:init pathinit  ${class}::$templatepath:opt     templatepathopt  ${class}::$templatepath:mod     templatepathmod  ${class}::$templatepath:init templatepathinit
  4056.  
  4057. if {[info exists pathopt]} { unset pathopt }
  4058. if {[info exists pathmod]} { unset pathmod }
  4059.  
  4060. array set pathmod  [array get templatepathmod]
  4061. array set pathopt  [array get templatepathopt]
  4062. array set pathinit [array get templatepathinit]
  4063.  
  4064. set Widget::_class($path) $class
  4065. foreach {option value} $options {
  4066. if {![info exists classopt($option)]} {
  4067. unset pathopt
  4068. unset pathmod
  4069. return -code error "unknown option \"$option\""
  4070. }
  4071.  
  4072. set optdesc $classopt($option)
  4073. set type    [lindex $optdesc 0]
  4074. if {[string equal $type "Synonym"]} {
  4075. set option    [lindex $optdesc 1]
  4076. set optdesc $classopt($option)
  4077. set type    [lindex $optdesc 0]
  4078. }
  4079.  
  4080. set arg [lindex $optdesc 3]
  4081. set pathopt($option)  [$Widget::_optiontype($type) $option $value $arg]
  4082. set pathinit($option) $pathopt($option)
  4083. }
  4084. }
  4085.  
  4086.  
  4087. proc Widget::parseArgs { class options {errorOut 1} } {
  4088. upvar 0 ${class}::opt classopt
  4089. upvar 0 ${class}::map classmap
  4090.  
  4091. foreach {option val} $options {
  4092. if {![info exists classopt($option)]} {
  4093. if {$errorOut} { return -code error "unknown option \"$option\"" }
  4094. continue
  4095. }
  4096.  
  4097. set optdesc $classopt($option)
  4098. set type    [lindex $optdesc 0]
  4099. if {[string equal $type "Synonym"]} {
  4100. set option  [lindex $optdesc 1]
  4101. set optdesc $classopt($option)
  4102. set type    [lindex $optdesc 0]
  4103. }
  4104.  
  4105. if {[string equal $type "TkResource"]} {
  4106. Widget::_get_tkwidget_options [lindex [lindex $optdesc 3] 0]
  4107. }
  4108.  
  4109. set val [$Widget::_optiontype($type) $option $val [lindex $optdesc 3]]
  4110.  
  4111. if {[info exists classmap($option)]} {
  4112. foreach {subpath subclass realopt} $classmap($option) {
  4113. lappend maps($subpath) $realopt $val
  4114. }
  4115. } else {
  4116. lappend maps($class) $option $val
  4117. }
  4118. }
  4119.  
  4120. return [array get maps]
  4121. }
  4122.  
  4123.  
  4124.  
  4125. proc Widget::initArgs { class options arrayName } {
  4126. upvar 1 $arrayName maps
  4127. upvar 0 ${class}::subpaths subpaths
  4128.  
  4129. array set maps [list $class {} :cmd {}]
  4130. foreach subpath [array names subpaths] {
  4131. set maps($subpath) [list]
  4132. }
  4133.  
  4134. array set maps [array get subpaths]
  4135.  
  4136. foreach {var val} [Widget::parseArgs $class $options] {
  4137. eval lappend maps($var) $val
  4138. }
  4139. }
  4140.  
  4141.  
  4142.  
  4143. proc Widget::splitArgs { options args } {
  4144. array set maps [list :cmd {}]
  4145. foreach class $args {
  4146. if {![info exists maps($class)]} { set maps($class) [list] }
  4147. array set maps [Widget::parseArgs $class $options 0]
  4148. }
  4149.  
  4150. return [array get maps]
  4151. }
  4152.  
  4153.  
  4154. proc Widget::optionExists { class option } {
  4155. return [info exists ${class}::opt($option)]
  4156. }
  4157.  
  4158.  
  4159. proc Widget::class { path } {
  4160. if {[info exists Widget::_class($path)]} { return $Widget::_class($path) }
  4161. return -code error "unknown widget $path"
  4162. }
  4163.  
  4164.  
  4165. proc Widget::destroy { path {unsetVariables 1} } {
  4166. variable _class
  4167. variable _inuse
  4168.  
  4169. if {[info exists _class($path)]} {
  4170. set class $_class($path)
  4171.  
  4172. if {[info exists _inuse($class)]} { incr _inuse($class) -1 }
  4173.  
  4174. if {![string equal [info commands $path] ""]} { rename $path "" }
  4175.  
  4176. foreach x {opt mod init} {
  4177. if {[info exists ${class}::$path:$x]} {
  4178. unset ${class}::$path:$x
  4179. }
  4180. }
  4181.  
  4182. if {$unsetVariables} { eval unset [info vars ${class}::$path:*] }
  4183.  
  4184. unset _class($path)
  4185. }
  4186. }
  4187.  
  4188.  
  4189. proc Widget::configure { path options } {
  4190. set len [llength $options]
  4191. if {$len < 2} { return [_get_configure $path $options] }
  4192. if {$len % 2} { return -code error "incorrect number of arguments" }
  4193.  
  4194. variable _class
  4195. variable _optiontype
  4196.  
  4197. set class $_class($path)
  4198. upvar 0 ${class}::opt  classopt
  4199. upvar 0 ${class}::map  classmap
  4200. upvar 0 ${class}::$path:opt pathopt
  4201. upvar 0 ${class}::$path:mod pathmod
  4202.  
  4203. set window [_get_window $class $path]
  4204. foreach {option value} $options {
  4205. if {![info exists classopt($option)]} {
  4206. return -code error "unknown option \"$option\""
  4207. }
  4208.  
  4209. set optdesc $classopt($option)
  4210. set type    [lindex $optdesc 0]
  4211. if {[string equal $type "Synonym"]} {
  4212. set option  [lindex $optdesc 1]
  4213. set optdesc $classopt($option)
  4214. set type    [lindex $optdesc 0]
  4215. }
  4216.  
  4217. if {[lindex $optdesc 2]} { continue }
  4218.  
  4219. set newval [$_optiontype($type) $option $value [lindex $optdesc 3]]
  4220.  
  4221. if {[info exists classmap($option)]} {
  4222. set window [_get_window $class $window]
  4223. foreach {subpath subclass realopt} $classmap($option) {
  4224. if {[string length $subclass]} {
  4225. set curval [${subclass}::cget $window$subpath $realopt]
  4226. ${subclass}::configure $window$subpath $realopt $newval
  4227. } else {
  4228. set curval [$window$subpath cget $realopt]
  4229. $window$subpath configure $realopt $newval
  4230. }
  4231. }
  4232. } else {
  4233. set curval $pathopt($option)
  4234. set pathopt($option) $newval
  4235. }
  4236.  
  4237. set pathmod($option) [expr {![string equal $newval $curval]}]
  4238. }
  4239.  
  4240. return
  4241. }
  4242.  
  4243.  
  4244. proc Widget::cget { path option } {
  4245. if {![info exists ::Widget::_class($path)]} {
  4246. return -code error "unknown widget \"$path\""
  4247. }
  4248.  
  4249. set class $::Widget::_class($path)
  4250. if {![info exists ${class}::opt($option)]} {
  4251. return -code error "unknown option \"$option\""
  4252. }
  4253.  
  4254. set optdesc [set ${class}::opt($option)]
  4255. set type    [lindex $optdesc 0]
  4256. if {[string equal $type "Synonym"]} {
  4257. set option [lindex $optdesc 1]
  4258. }
  4259.  
  4260. if {[info exists ${class}::map($option)]} {
  4261. foreach {subpath subclass realopt} [set ${class}::map($option)] {break}
  4262. set path "[_get_window $class $path]$subpath"
  4263. return [$path cget $realopt]
  4264. }
  4265. upvar 0 ${class}::$path:opt pathopt
  4266. set pathopt($option)
  4267. }
  4268.  
  4269.  
  4270. proc Widget::subcget { path subwidget } {
  4271. set class $::Widget::_class($path)
  4272. upvar 0 ${class}::$path:opt pathopt
  4273. upvar 0 ${class}::map$subwidget submap
  4274. upvar 0 ${class}::$path:init pathinit
  4275.  
  4276. set result [list]
  4277. foreach realopt [array names submap] {
  4278. if {[info exists pathinit($submap($realopt))]} {
  4279. lappend result $realopt $pathopt($submap($realopt))
  4280. }
  4281. }
  4282. return $result
  4283. }
  4284.  
  4285.  
  4286. proc Widget::hasChanged { path option varName } {
  4287. upvar 1 $varName value
  4288. Widget::getVariable $path mod pathmod
  4289.  
  4290. set value   [Widget::cget $path $option]
  4291. set result  $pathmod($option)
  4292. set pathmod($option) 0
  4293.  
  4294. return $result
  4295. }
  4296.  
  4297. proc Widget::hasChangedX { path option args } {
  4298. set class $::Widget::_class($path)
  4299. upvar 0 ${class}::$path:mod pathmod
  4300.  
  4301. set result  $pathmod($option)
  4302. set pathmod($option) 0
  4303. foreach option $args {
  4304. lappend result $pathmod($option)
  4305. set pathmod($option) 0
  4306. }
  4307.  
  4308. set result
  4309. }
  4310.  
  4311.  
  4312. proc Widget::anyChangedX { path args } {
  4313. set class $::Widget::_class($path)
  4314. upvar 0 ${class}::$path:mod pathmod
  4315.  
  4316. set result 0
  4317. foreach option $args {
  4318. incr result $pathmod($option)
  4319. set pathmod($option) 0
  4320. }
  4321. return $result
  4322. }
  4323.  
  4324.  
  4325. proc Widget::getoption { path option } {
  4326. set class $::Widget::_class($path)
  4327. upvar 0 ${class}::${path}:opt pathopt
  4328. set pathopt($option)
  4329. }
  4330.  
  4331.  
  4332. proc Widget::setoption { path args } {
  4333. set class $::Widget::_class($path)
  4334. upvar 0 ${class}::${path}:opt pathopt
  4335. foreach [list option value] $args {
  4336. set pathopt($option) $value
  4337. }
  4338. }
  4339.  
  4340.  
  4341. proc Widget::getMegawidgetOption { path option } {
  4342. set class $::Widget::_class($path)
  4343. upvar 0 ${class}::${path}:opt pathopt
  4344. set pathopt($option)
  4345. }
  4346.  
  4347.  
  4348. proc Widget::setMegawidgetOption { path option value } {
  4349. set class $::Widget::_class($path)
  4350. upvar 0 ${class}::${path}:opt pathopt
  4351. set pathopt($option) $value
  4352. }
  4353.  
  4354.  
  4355. proc Widget::_get_window { class path } {
  4356. set idx [expr {[string last "#" $path] + 1}]
  4357. if {$idx && [string equal [string range $path $idx end] $class]} {
  4358. return [string range $path 0 [expr {$idx - 2}]]
  4359. }
  4360. return $path
  4361. }
  4362.  
  4363.  
  4364. proc Widget::_get_configure { path options } {
  4365. variable _class
  4366.  
  4367. set class $_class($path)
  4368. upvar 0 ${class}::opt classopt
  4369. upvar 0 ${class}::$path:opt pathopt
  4370.  
  4371. if {[llength $options] == 1} {
  4372. set option  [lindex $options 0]
  4373. if { ![info exists classopt($option)] } {
  4374. return -code error "unknown option \"$option\""
  4375. }
  4376. set optdesc $classopt($option)
  4377. set type    [lindex $optdesc 0]
  4378. if { [string equal $type "Synonym"] } {
  4379. set option  [lindex $optdesc 1]
  4380. set optdesc $classopt($option)
  4381. set type    [lindex $optdesc 0]
  4382. }
  4383. if { [string equal $type "TkResource"] } {
  4384. set alt [lindex [lindex $optdesc 3] 1]
  4385. } else {
  4386. set alt ""
  4387. }
  4388.  
  4389. set res [list $option]
  4390. eval lappend res [_configure_option $option $alt]
  4391. lappend res [lindex $optdesc 1] [${class}::cget $path $option]
  4392.  
  4393. return $res
  4394. }
  4395.  
  4396.  
  4397. set result [list]
  4398. foreach option [lsort [array names classopt]] {
  4399. set alt     ""
  4400. set syn     ""
  4401. set optdesc $classopt($option)
  4402. set type    [lindex $optdesc 0]
  4403.  
  4404. if {[string equal $type "Synonym"]} {
  4405. set syn     $option
  4406. set option  [lindex $optdesc 1]
  4407. set optdesc $classopt($option)
  4408. set type    [lindex $optdesc 0]
  4409. }
  4410.  
  4411. if {[string equal $type "TkResource"]} {
  4412. set alt [lindex [lindex $optdesc 3] 1]
  4413. }
  4414.  
  4415. set res [_configure_option $option $alt]
  4416. if {![string length $syn]} {
  4417. lappend result [concat $option $res  [list [lindex $optdesc 1]] [list [cget $path $option]]]
  4418. } else {
  4419. lappend result [list $syn [lindex $res 0]]
  4420. }
  4421. }
  4422.  
  4423. return $result
  4424. }
  4425.  
  4426.  
  4427. proc Widget::_configure_option { option altopt } {
  4428. variable _optiondb
  4429. variable _optionclass
  4430.  
  4431. if {[info exists _optiondb($option)]} {
  4432. set optdb $_optiondb($option)
  4433. } else {
  4434. set optdb [string range $option 1 end]
  4435. }
  4436.  
  4437. if {[info exists _optionclass($option)]} {
  4438. set optclass $_optionclass($option)
  4439. } elseif {[string length $altopt]} {
  4440. if {[info exists _optionclass($altopt)]} {
  4441. set optclass $_optionclass($altopt)
  4442. } else {
  4443. set optclass [string range $altopt 1 end]
  4444. }
  4445. } else {
  4446. set optclass [string range $option 1 end]
  4447. }
  4448.  
  4449. return [list $optdb $optclass]
  4450. }
  4451.  
  4452.  
  4453. proc Widget::_get_tkwidget_options { tkwidget } {
  4454. variable _tk_widget
  4455. variable _optiondb
  4456. variable _optionclass
  4457.  
  4458. if {![info exists _tk_widget($tkwidget)]} {
  4459. set widget [Widget::CreateTempWidget $tkwidget $tkwidget]
  4460.  
  4461. set config [$widget configure]
  4462. foreach optlist $config {
  4463. set opt [lindex $optlist 0]
  4464. if {[llength $optlist] == 2} {
  4465. set refsyn [lindex $optlist 1]
  4466.  
  4467. set idx [lsearch $config [list * $refsyn *]]
  4468. if {$idx == -1} {
  4469. if {[string index $refsyn 0] == "-"} {
  4470. set idx [lsearch $config [list $refsyn * *]]
  4471. } else {
  4472. set refsyn [string tolower $refsyn]
  4473. set idx [lsearch $config [list -$refsyn * *]]
  4474. }
  4475.  
  4476. if {$idx == -1} {
  4477. return -code error "can't find option of synonym $opt"
  4478. }
  4479. }
  4480.  
  4481. set syn [lindex [lindex $config $idx] 0]
  4482. set def [lindex [lindex $config $idx] 4]
  4483. lappend _tk_widget($tkwidget) [list $opt $syn $def]
  4484. } else {
  4485. set def [lindex $optlist 4]
  4486. lappend _tk_widget($tkwidget) [list $opt $def]
  4487. set _optiondb($opt)    [lindex $optlist 1]
  4488. set _optionclass($opt) [lindex $optlist 2]
  4489. }
  4490. }
  4491. }
  4492.  
  4493. return $_tk_widget($tkwidget)
  4494. }
  4495.  
  4496.  
  4497. proc Widget::_test_tkresource { option value arg } {
  4498. set tkwidget [lindex $arg 0]
  4499. set realopt  [lindex $arg 1]
  4500. set path     [Widget::CreateTempWidget $tkwidget $tkwidget]
  4501. set old      [$path cget $realopt]
  4502. $path configure $realopt $value
  4503. set res      [$path cget $realopt]
  4504. $path configure $realopt $old
  4505. return $res
  4506. }
  4507.  
  4508.  
  4509. proc Widget::_test_bwresource { option value arg } {
  4510. return -code error "bad option type BwResource in widget"
  4511. }
  4512.  
  4513.  
  4514. proc Widget::_test_synonym { option value arg } {
  4515. return -code error "bad option type Synonym in widget"
  4516. }
  4517.  
  4518. proc Widget::_test_color { option value arg } {
  4519. if {[info exists ::BWidget::colors($value)]} {
  4520. set value $::BWidget::colors($value)
  4521. }
  4522.  
  4523. if {[catch {winfo rgb . $value} color]} {
  4524. return -code error  "bad $option value \"$value\": must be a colorname or #RRGGBB"
  4525. }
  4526.  
  4527. return $value
  4528. }
  4529.  
  4530.  
  4531. proc Widget::_test_color2 { option value arg } {
  4532. if {![string length $value]} { return }
  4533.  
  4534. if {[info exists ::BWidget::colors($value)]} {
  4535. set value $::BWidget::colors($value)
  4536. }
  4537.  
  4538. if {[catch {winfo rgb . $value} color]} {
  4539. return -code error  "bad $option value \"$value\": must be a colorname or #RRGGBB"
  4540. }
  4541.  
  4542. return $value
  4543. }
  4544.  
  4545.  
  4546. proc Widget::_test_string { option value arg } {
  4547. return $value
  4548. }
  4549.  
  4550.  
  4551. proc Widget::_test_flag { option value arg } {
  4552. set len [string length $value]
  4553. set res ""
  4554. for {set i 0} {$i < $len} {incr i} {
  4555. set c [string index $value $i]
  4556. if {[string first $c $arg] == -1} {
  4557. set name [string range $option 1 end]
  4558. return -code error [BWidget::badOptionString $name $value $arg]
  4559. }
  4560. if {[string first $c $res] == -1} { append res $c }
  4561. }
  4562. return $res
  4563. }
  4564.  
  4565.  
  4566. proc Widget::_test_enum { option value arg } {
  4567. if {[lsearch -exact $arg $value] == -1} {
  4568. set name [string range $option 1 end]
  4569. return -code error [BWidget::badOptionString $name $value $arg]
  4570. }
  4571. return $value
  4572. }
  4573.  
  4574.  
  4575. proc Widget::_test_int { option value arg } {
  4576. set map [list %d $value]
  4577. if {![string is int -strict $value]
  4578. || ([string length $arg] && ![expr [string map $map $arg]])} {
  4579. return -code error  "bad $option value \"$value\": must be integer ($arg)"
  4580. }
  4581. return $value
  4582. }
  4583.  
  4584.  
  4585. proc Widget::_test_boolean { option value arg } {
  4586. if {![string is boolean -strict $value]} {
  4587. set name [string range $option 1 end]
  4588. return -code error [BWidget::badOptionString $name $value boolean]
  4589. }
  4590.  
  4591. return [string is true $value]
  4592. }
  4593.  
  4594.  
  4595. proc Widget::_test_boolean2 { option value arg } {
  4596. if {![string is boolean $value]} {
  4597. set name [string range $option 1 end]
  4598. set opts [list empty boolean]
  4599. return -code error [BWidget::badOptionString $name $value $opts]
  4600. }
  4601.  
  4602. if {[string length $value]} { return [string is true $value] }
  4603. }
  4604.  
  4605.  
  4606. proc Widget::_test_padding { option values arg } {
  4607. set len [llength $values]
  4608. if {$len < 1 || $len > 2} {
  4609. return -code error  "bad pad value \"$values\": must be positive screen distance"
  4610. }
  4611.  
  4612. foreach value $values {
  4613. set map [list %d $value]
  4614. if {![string is int -strict $value]
  4615. || ([string length $arg] && ![expr [string map $map $arg]])} {
  4616. return -code error  "bad pad value \"$value\": must be positive screen distance"
  4617. }
  4618. }
  4619. return $values
  4620. }
  4621.  
  4622.  
  4623. proc Widget::_get_padding { args } {
  4624. if {[llength $args] == 2} {
  4625. set padding [lindex $args 0]
  4626. set index   [lindex $args 1]
  4627. } elseif {[llength $args] == 3} {
  4628. set path    [lindex $args 0]
  4629. set option  [lindex $args 1]
  4630. set index   [lindex $args 2]
  4631. set padding [Widget::cget $path $option]
  4632. }
  4633. set val [lindex $padding $index]
  4634. if {![string length $val]} { set val [lindex $padding 0] }
  4635. return $val
  4636. }
  4637.  
  4638.  
  4639. proc Widget::focusNext { w } {
  4640. set cur $w
  4641. while 1 {
  4642.  
  4643.  
  4644. set parent $cur
  4645. set children [winfo children $cur]
  4646. set i -1
  4647.  
  4648.  
  4649. while 1 {
  4650. incr i
  4651. if {$i < [llength $children]} {
  4652. set cur [lindex $children $i]
  4653. if {[winfo toplevel $cur] == $cur} {
  4654. continue
  4655. } else {
  4656. break
  4657. }
  4658. }
  4659.  
  4660.  
  4661. set cur $parent
  4662. if {[winfo toplevel $cur] == $cur} {
  4663. break
  4664. }
  4665. set parent [winfo parent $parent]
  4666. set children [winfo children $parent]
  4667. set i [lsearch -exact $children $cur]
  4668. }
  4669. if {($cur == $w) || [focusOK $cur]} {
  4670. return $cur
  4671. }
  4672. }
  4673. }
  4674.  
  4675.  
  4676. proc Widget::focusPrev { w } {
  4677. set cur $w
  4678. while 1 {
  4679.  
  4680.  
  4681. if {[winfo toplevel $cur] == $cur}  {
  4682. set parent $cur
  4683. set children [winfo children $cur]
  4684. set i [llength $children]
  4685. } else {
  4686. set parent [winfo parent $cur]
  4687. set children [winfo children $parent]
  4688. set i [lsearch -exact $children $cur]
  4689. }
  4690.  
  4691.  
  4692. while {$i > 0} {
  4693. incr i -1
  4694. set cur [lindex $children $i]
  4695. if {[winfo toplevel $cur] == $cur} {
  4696. continue
  4697. }
  4698. set parent $cur
  4699. set children [winfo children $parent]
  4700. set i [llength $children]
  4701. }
  4702. set cur $parent
  4703. if {($cur == $w) || [focusOK $cur]} {
  4704. return $cur
  4705. }
  4706. }
  4707. }
  4708.  
  4709.  
  4710. proc Widget::focusOK { w } {
  4711. set code [catch {$w cget -takefocus} value]
  4712. if {$code == 1} { return 0 }
  4713.  
  4714. if {!$code && [string length $value]} {
  4715. if {$value == 0} {
  4716. return 0
  4717. } elseif {$value == 1} {
  4718. return [winfo viewable $w]
  4719. } else {
  4720. set value [uplevel \#0 $value $w]
  4721. if {[string length $value]} { return $value }
  4722. }
  4723. }
  4724.  
  4725. if {![winfo viewable $w]} { return 0 }
  4726.  
  4727. set code [catch {$w cget -state} value]
  4728. if {!$code && [string equal $value "disabled"]} { return 0 }
  4729.  
  4730. set code [catch {$w cget -editable} value]
  4731. if {!$code && $value == 0} { return 0 }
  4732.  
  4733. set top [winfo toplevel $w]
  4734. foreach tag [bindtags $w] {
  4735. if {![string equal $tag $top]
  4736. && ![string equal $tag "all"]
  4737. && [string match *Key* [bind $tag]]} {
  4738. return 1
  4739. }
  4740. }
  4741. return 0
  4742. }
  4743.  
  4744.  
  4745. proc Widget::traverseTo { w } {
  4746. set focus [focus]
  4747. if {[string length $focus]} {
  4748. event generate $focus <<TraverseOut>>
  4749. }
  4750. focus $w
  4751.  
  4752. event generate $w <<TraverseIn>>
  4753. }
  4754.  
  4755.  
  4756.  
  4757. proc Widget::varForOption { path option } {
  4758. variable _class
  4759. variable _optiontype
  4760.  
  4761. set class $_class($path)
  4762. upvar 0 ${class}::$path:opt pathopt
  4763.  
  4764. if {![info exists pathopt($option)]} {
  4765. return -code error "unable to find variable for option \"$option\""
  4766. }
  4767.  
  4768. return ::Widget::${class}::$path:opt($option)
  4769. }
  4770.  
  4771.  
  4772. proc Widget::widgetVar { path varName } {
  4773. set class $Widget::_class($path)
  4774. return ::Widget::${class}::$path:$varName
  4775. }
  4776.  
  4777.  
  4778. proc Widget::getVariable { path varName {newVarName ""} } {
  4779. if {![string length $newVarName]} { set newVarName $varName }
  4780. uplevel 1 [list upvar \#0 [Widget::widgetVar $path $varName] $newVarName]
  4781. }
  4782.  
  4783.  
  4784. proc Widget::options { path args } {
  4785. if {[llength $args]} {
  4786. foreach option $args {
  4787. lappend options [_get_configure $path $option]
  4788. }
  4789. } else {
  4790. set options [_get_configure $path {}]
  4791. }
  4792.  
  4793. set result [list]
  4794. foreach list $options {
  4795. if {[llength $list] < 5} { continue }
  4796. lappend result [lindex $list 0] [lindex $list end]
  4797. }
  4798. return $result
  4799. }
  4800.  
  4801.  
  4802. proc Widget::getOption { option default args } {
  4803. foreach widget $args {
  4804. set value  [Widget::getoption $widget $option]
  4805. if {$value != $default} { break }
  4806. }
  4807. return $value
  4808. }
  4809.  
  4810.  
  4811. proc Widget::cgetOption { option default args } {
  4812. foreach widget $args {
  4813. set value  [Widget::cget $widget $option]
  4814. if {$value != $default} { break }
  4815. }
  4816. return $value
  4817. }
  4818.  
  4819.  
  4820. proc Widget::nextIndex { path node } {
  4821. Widget::getVariable $path autoIndex
  4822. if {![info exists autoIndex]} { set autoIndex -1 }
  4823. return [string map [list #auto [incr autoIndex]] $node]
  4824. }
  4825.  
  4826.  
  4827. proc Widget::exists { path } {
  4828. return [info exists ::Widget::_class($path)]
  4829. }
  4830.  
  4831.  
  4832. proc Widget::theme {{bool {}}} {
  4833. variable _theme
  4834. if {[llength [info level 0]] == 2} {
  4835. if {[catch {package require tile 0.6}]
  4836. && [catch {package require tile 1}]} {
  4837. return -code error "BWidget's theming requires tile 0.6+"
  4838. } else {
  4839. catch {style default BWSlim.Toolbutton -padding 0}
  4840. }
  4841. set _theme [string is true -strict $bool]
  4842. }
  4843. return $_theme
  4844. }
  4845.  
  4846.  
  4847. namespace eval BWidget {
  4848. variable _gstack [list]
  4849. variable _fstack [list]
  4850. }
  4851.  
  4852.  
  4853. proc BWidget::use { args } {
  4854. variable includes
  4855.  
  4856. if {![llength $args]} {
  4857. BWidget::use aqua [expr {$::tcl_version >= 8.4
  4858. && [string equal [tk windowingsystem] "aqua"]}]
  4859. return
  4860. }
  4861.  
  4862. set package [lindex $args 0]
  4863. set value   [lindex $args 1]
  4864. set force   [string equal [lindex $args 2] "-force"]
  4865. if {![string length $value]} { set value 1 }
  4866.  
  4867. if {$value && ($force || ![info exists includes($package)])} {
  4868. switch -- $package {
  4869. "aqua" {
  4870.  
  4871. }
  4872.  
  4873. "png" {
  4874. if {[catch { package require img::png } err]} {
  4875. if {[catch { package require tkpng } err]} {
  4876. return -code error "Could not find img::png or tkpng package to support PNG data"
  4877. } else {
  4878. set ::BWidget::imageFormat png
  4879. }
  4880. } else {
  4881. set ::BWidget::imageFormat PNG
  4882. }
  4883.  
  4884. set ::BWidget::iconLibraryFile  [file join $::BWidget::imageDir BWidget.png.tkico]
  4885. }
  4886.  
  4887. "ttk" {
  4888. Widget::theme 1
  4889.  
  4890. variable ::BWidget::colors
  4891.  
  4892. foreach {opt val} [style configure .] {
  4893. switch -- $opt {
  4894. "-background" {
  4895. set colors(SystemButtonFace) $val
  4896. }
  4897.  
  4898. "-foreground" {
  4899. set colors(SystemWindowText) $val
  4900. }
  4901.  
  4902. "-selectbackground" {
  4903. set colors(SystemHighlight) $val
  4904. }
  4905.  
  4906. "-selectforeground" {
  4907. set colors(SystemHighlightText) $val
  4908. }
  4909.  
  4910. "-troughcolor" {
  4911. set colors(SystemScrollbar) $val
  4912. }
  4913. }
  4914. }
  4915. }
  4916. }
  4917. }
  4918.  
  4919. set includes($package) $value
  4920. return $value
  4921. }
  4922.  
  4923.  
  4924. proc BWidget::using { package } {
  4925. if {[info exists ::BWidget::includes($package)]} {
  4926. return $::BWidget::includes($package)
  4927. }
  4928. return 0
  4929. }
  4930.  
  4931.  
  4932. proc BWidget::globalexists { varName } {
  4933. return [uplevel \#0 [list info exists $varName]]
  4934. }
  4935.  
  4936.  
  4937. proc BWidget::setglobal { varName value } {
  4938. return [uplevel \#0 [list set $varName $value]]
  4939. }
  4940.  
  4941.  
  4942. proc BWidget::getglobal { varName } {
  4943. return [uplevel \#0 [list set $varName]]
  4944. }
  4945.  
  4946.  
  4947. proc BWidget::traceglobal { cmd varName args } {
  4948. return [uplevel \#0 [list trace $cmd $varName] $args]
  4949. }
  4950.  
  4951.  
  4952.  
  4953. proc BWidget::lreorder { list neworder } {
  4954. set pos     0
  4955. set newlist {}
  4956. foreach e $neworder {
  4957. if { [lsearch -exact $list $e] != -1 } {
  4958. lappend newlist $e
  4959. set tabelt($e)  1
  4960. }
  4961. }
  4962. set len [llength $newlist]
  4963. if { !$len } {
  4964. return $list
  4965. }
  4966. if { $len == [llength $list] } {
  4967. return $newlist
  4968. }
  4969. set pos 0
  4970. foreach e $list {
  4971. if { ![info exists tabelt($e)] } {
  4972. set newlist [linsert $newlist $pos $e]
  4973. }
  4974. incr pos
  4975. }
  4976. return $newlist
  4977. }
  4978.  
  4979.  
  4980. proc BWidget::lremove { list args } {
  4981. foreach elem $args {
  4982. set x [lsearch -exact $list $elem]
  4983. if {$x > -1} { set list [lreplace $list $x $x] }
  4984. }
  4985. return $list
  4986. }
  4987.  
  4988.  
  4989. proc BWidget::lassign { list args } {
  4990. foreach elem $list varName $args {
  4991. if {[string equal $varName ""]} { break }
  4992. uplevel 1 [list set $varName $elem]
  4993. }
  4994. }
  4995.  
  4996.  
  4997. proc BWidget::assert { exp {msg ""}} {
  4998. set res [uplevel 1 expr $exp]
  4999. if { !$res} {
  5000. if { $msg == "" } {
  5001. return -code error "Assertion failed: {$exp}"
  5002. } else {
  5003. return -code error $msg
  5004. }
  5005. }
  5006. }
  5007.  
  5008.  
  5009. proc BWidget::clonename { menu } {
  5010. set path     ""
  5011. set menupath ""
  5012. set found    0
  5013. foreach widget [lrange [split $menu "."] 1 end] {
  5014. if { $found || [winfo class "$path.$widget"] == "Menu" } {
  5015. set found 1
  5016. append menupath "#" $widget
  5017. append path "." $menupath
  5018. } else {
  5019. append menupath "#" $widget
  5020. append path "." $widget
  5021. }
  5022. }
  5023. return $path
  5024. }
  5025.  
  5026.  
  5027. proc BWidget::getname { name } {
  5028. if { [string length $name] } {
  5029. set text [option get . "${name}Name" ""]
  5030. if { [string length $text] } {
  5031. return [parsetext $text]
  5032. }
  5033. }
  5034. return {}
  5035. }
  5036.  
  5037.  
  5038. proc BWidget::parsetext { text } {
  5039. set result ""
  5040. set index  -1
  5041. set start  0
  5042. while { [string length $text] } {
  5043. set idx [string first "&" $text]
  5044. if { $idx == -1 } {
  5045. append result $text
  5046. set text ""
  5047. } else {
  5048. set char [string index $text [expr {$idx+1}]]
  5049. if { $char == "&" } {
  5050. append result [string range $text 0 $idx]
  5051. set    text   [string range $text [expr {$idx+2}] end]
  5052. set    start  [expr {$start+$idx+1}]
  5053. } else {
  5054. append result [string range $text 0 [expr {$idx-1}]]
  5055. set    text   [string range $text [expr {$idx+1}] end]
  5056. incr   start  $idx
  5057. set    index  $start
  5058. }
  5059. }
  5060. }
  5061. return [list $result $index]
  5062. }
  5063.  
  5064.  
  5065. proc BWidget::get3dcolor { path bgcolor {multiplier 0} {divideBy 100} } {
  5066. set fmt "#%04x%04x%04x"
  5067.  
  5068. if {$multiplier} {
  5069. foreach val [winfo rgb $path $bgcolor] {
  5070. lappend list [expr {$multiplier * $val / $divideBy}]
  5071. }
  5072. return [eval format $fmt $list]
  5073. }
  5074.  
  5075. if {[string equal $bgcolor "SystemButtonFace"]} {
  5076. lappend list System3dDarkShadow SystemButtonHighlight
  5077. lappend list SystemButtonShadow System3dLight
  5078. return $list
  5079. }
  5080.  
  5081. foreach val [winfo rgb $path $bgcolor] {
  5082. lappend dark  [expr {48 * $val / 100}]
  5083. lappend dark2 [expr {72 * $val / 100}]
  5084.  
  5085. set tmp1 [expr {14*$val/10}]
  5086. if { $tmp1 > 65535 } { set tmp1 65535 }
  5087.  
  5088. set tmp2 [expr {(65535+$val)/2}]
  5089. lappend light  [expr {($tmp1 > $tmp2) ? $tmp1:$tmp2}]
  5090.  
  5091. set tmp [expr {92 * $val / 90}]
  5092. lappend light2 [expr {($tmp > 65535) ? 65535 : $tmp}]
  5093. }
  5094.  
  5095. lappend list [eval format $fmt $dark]
  5096. lappend list [eval format $fmt $light]
  5097. lappend list [eval format $fmt $dark2]
  5098. lappend list [eval format $fmt $light2]
  5099.  
  5100. return $list
  5101. }
  5102.  
  5103.  
  5104. proc BWidget::color2hex { path color } {
  5105. if {[catch { winfo rgb $path $color } rgb]} {
  5106. return -code error "Invalid color '$color'"
  5107. }
  5108. foreach {r g b} $rgb { break }
  5109. return [format {#%4.4x%4.4x%4.4x} $r $g $b]
  5110. }
  5111.  
  5112.  
  5113. proc BWidget::getGradientColors { col1Str col2Str size {offset 0} } {
  5114. if {[catch { winfo rgb . $col1Str } color1]} {
  5115. return -code error "Invalid color '$col1Str'"
  5116. }
  5117.  
  5118. if {[catch { winfo rgb . $col2Str } color2]} {
  5119. return -code error "Invalid color '$col2Str'"
  5120. }
  5121.  
  5122. set max [expr {$size - $offset}]
  5123.  
  5124. foreach {r1 g1 b1} $color1 { break }
  5125. foreach {r2 g2 b2} $color2 { break }
  5126. set rRange [expr {double($r2) - $r1}]
  5127. set gRange [expr {double($g2) - $g1}]
  5128. set bRange [expr {double($b2) - $b1}]
  5129. set rRatio [expr {$rRange / $max}]
  5130. set gRatio [expr {$gRange / $max}]
  5131. set bRatio [expr {$bRange / $max}]
  5132.  
  5133. set colors [list]
  5134.  
  5135. for {set i 0} {$i < $offset} {incr i} {
  5136. lappend colors [format {#%4.4x%4.4x%4.4x} $r1 $g1 $b1]
  5137. }
  5138.  
  5139. for {set i 0} {$i < $max} {incr i} {
  5140. set nR [expr {int( $r1 + ($rRatio * $i) )}]
  5141. set nG [expr {int( $g1 + ($gRatio * $i) )}]
  5142. set nB [expr {int( $b1 + ($bRatio * $i) )}]
  5143. lappend colors [format {#%4.4x%4.4x%4.4x} $nR $nG $nB]
  5144. }
  5145.  
  5146. return $colors
  5147. }
  5148.  
  5149.  
  5150. proc BWidget::XLFDfont { cmd args } {
  5151. switch -- $cmd {
  5152. create {
  5153. set font "-*-*-*-*-*-*-*-*-*-*-*-*-*-*"
  5154. }
  5155. configure {
  5156. set font [lindex $args 0]
  5157. set args [lrange $args 1 end]
  5158. }
  5159. default {
  5160. return -code error "XLFDfont: command incorrect: $cmd"
  5161. }
  5162. }
  5163. set lfont [split $font "-"]
  5164. if { [llength $lfont] != 15 } {
  5165. return -code error "XLFDfont: description XLFD incorrect: $font"
  5166. }
  5167.  
  5168. foreach {option value} $args {
  5169. switch -- $option {
  5170. -foundry { set index 1 }
  5171. -family  { set index 2 }
  5172. -weight  { set index 3 }
  5173. -slant   { set index 4 }
  5174. -size    { set index 7 }
  5175. default  { return -code error "XLFDfont: option incorrect: $option" }
  5176. }
  5177. set lfont [lreplace $lfont $index $index $value]
  5178. }
  5179. return [join $lfont "-"]
  5180. }
  5181.  
  5182.  
  5183.  
  5184. proc BWidget::place { path w h args } {
  5185. update idletasks
  5186. if {$w == 0} { set w [winfo reqwidth  $path] }
  5187. if {$h == 0} { set h [winfo reqheight $path] }
  5188.  
  5189. set arglen [llength $args]
  5190. if { $arglen > 3 } {
  5191. return -code error "BWidget::place: bad number of argument"
  5192. }
  5193.  
  5194. if { $arglen > 0 } {
  5195. set where [lindex $args 0]
  5196. set list  [list "at" "center" "left" "right" "above" "below"]
  5197. set idx   [lsearch -exact $list $where]
  5198. if { $idx == -1 } {
  5199. return -code error [BWidget::badOptionString position $where $list]
  5200. }
  5201. if { $idx == 0 } { ## at
  5202. set err [catch {
  5203. set x [expr int([lindex $args 1])]
  5204. set y [expr int([lindex $args 2])]
  5205. }]
  5206. if { $err } {
  5207. return -code error "BWidget::place: incorrect position"
  5208. }
  5209. if {[string equal $::tcl_platform(platform) "windows"]} {
  5210. if {[string index [lindex $args 1] 0] != "-"} {
  5211. set x "+$x"
  5212. }
  5213. if {[string index [lindex $args 2] 0] != "-"} {
  5214. set y "+$y"
  5215. }
  5216. } else {
  5217. if { $x >= 0 } {
  5218. set x "+$x"
  5219. }
  5220. if { $y >= 0 } {
  5221. set y "+$y"
  5222. }
  5223. }
  5224. } else {
  5225. if { $arglen == 2 } {
  5226. set widget [lindex $args 1]
  5227. if { ![winfo exists $widget] } {
  5228. set msg "BWidget::place: \"$widget\" does not exist"
  5229. return -code error $msg
  5230. }
  5231. } else {
  5232. set widget .
  5233. }
  5234.  
  5235. set sw    [winfo screenwidth  $path]
  5236. set sh    [winfo screenheight $path]
  5237. set rootx [winfo rootx $widget]
  5238. set rooty [winfo rooty $widget]
  5239.  
  5240. if { $idx == 1 } { ## center
  5241. if { $arglen == 2 } {
  5242. set x0 [expr {$rootx + ([winfo width  $widget] - $w)/2}]
  5243. set y0 [expr {$rooty + ([winfo height $widget] - $h)/2}]
  5244. } else {
  5245. set x0 [expr {($sw - $w)/2 - [winfo vrootx $path]}]
  5246. set y0 [expr {($sh - $h)/2 - [winfo vrooty $path]}]
  5247. }
  5248. set x "+$x0"
  5249. set y "+$y0"
  5250. if {$::tcl_platform(platform) != "windows"} {
  5251. if { $x0+$w > $sw } {set x "-0"; set x0 [expr {$sw-$w}]}
  5252. if { $x0 < 0 }      {set x "+0"}
  5253. if { $y0+$h > $sh } {set y "-0"; set y0 [expr {$sh-$h}]}
  5254. if { $y0 < 0 }      {set y "+0"}
  5255. }
  5256. } else {
  5257. set x0 $rootx
  5258. set y0 $rooty
  5259. set x1 [expr {$x0 + [winfo width  $widget]}]
  5260. set y1 [expr {$y0 + [winfo height $widget]}]
  5261. if { $idx == 2 || $idx == 3 } { ## left or right
  5262. set y "+$y0"
  5263. if {$::tcl_platform(platform) != "windows"} {
  5264. if { $y0+$h > $sh } {set y "-0"; set y0 [expr {$sh-$h}]}
  5265. if { $y0 < 0 }      {set y "+0"}
  5266. }
  5267. if { $idx == 2 } {
  5268. if { $x0 >= $w } {
  5269. set x [expr {$x0-$sw}]
  5270. } elseif { $x1+$w <= $sw } {
  5271. set x "+$x1"
  5272. } else {
  5273. set x "+0"
  5274. }
  5275. } else {
  5276. if { $x1+$w <= $sw } {
  5277. set x "+$x1"
  5278. } elseif { $x0 >= $w } {
  5279. set x [expr {$x0-$sw}]
  5280. } else {
  5281. set x "-0"
  5282. }
  5283. }
  5284. } else { ## above or below
  5285. set x "+$x0"
  5286. if {[string equal $::tcl_platform(platform) "windows"]} {
  5287. if { $x0+$w > $sw } {set x "-0"; set x0 [expr {$sw-$w}]}
  5288. if { $x0 < 0 }      {set x "+0"}
  5289. }
  5290. if { $idx == 4 } {
  5291. if { $h <= $y0 } {
  5292. set y [expr {$y0-$sh}]
  5293. } elseif { $y1+$h <= $sh } {
  5294. set y "+$y1"
  5295. } else {
  5296. set y "+0"
  5297. }
  5298. } else {
  5299. if { $y1+$h <= $sh } {
  5300. set y "+$y1"
  5301. } elseif { $h <= $y0 } {
  5302. set y [expr {$y0-$sh}]
  5303. } else {
  5304. set y "-0"
  5305. }
  5306. }
  5307. }
  5308. }
  5309. }
  5310.  
  5311. if {[string is integer [string index $x 0]]} { set x +$x }
  5312. if {[string is integer [string index $y 0]]} { set y +$y }
  5313.  
  5314. wm geometry $path "${w}x${h}${x}${y}"
  5315. } else {
  5316. wm geometry $path "${w}x${h}"
  5317. }
  5318. update idletasks
  5319. }
  5320.  
  5321.  
  5322. proc BWidget::grab { option path } {
  5323. variable _gstack
  5324.  
  5325. if { $option == "release" } {
  5326. catch {::grab release $path}
  5327. while { [llength $_gstack] } {
  5328. set grinfo  [lindex $_gstack end]
  5329. set _gstack [lreplace $_gstack end end]
  5330. foreach {oldg mode} $grinfo {
  5331. if { ![string equal $oldg $path] && [winfo exists $oldg] } {
  5332. if { $mode == "global" } {
  5333. catch {::grab -global $oldg}
  5334. } else {
  5335. catch {::grab $oldg}
  5336. }
  5337. return
  5338. }
  5339. }
  5340. }
  5341. } else {
  5342. set oldg [::grab current]
  5343. if { $oldg != "" } {
  5344. lappend _gstack [list $oldg [::grab status $oldg]]
  5345. }
  5346. if { $option == "global" } {
  5347. ::grab -global $path
  5348. } else {
  5349. ::grab $path
  5350. }
  5351. }
  5352. }
  5353.  
  5354.  
  5355. proc BWidget::focus { option path {refocus 1} } {
  5356. variable _fstack
  5357.  
  5358. if { $option == "release" } {
  5359. while { [llength $_fstack] } {
  5360. set oldf [lindex $_fstack end]
  5361. set _fstack [lreplace $_fstack end end]
  5362. if { ![string equal $oldf $path] && [winfo exists $oldf] } {
  5363. if {$refocus} {catch {::focus -force $oldf}}
  5364. return
  5365. }
  5366. }
  5367. } elseif { $option == "set" } {
  5368. lappend _fstack [::focus]
  5369. ::focus -force $path
  5370. }
  5371. }
  5372.  
  5373.  
  5374. proc BWidget::refocus {container component} {
  5375. if { [string equal $container [::focus]] } {
  5376. ::focus $component
  5377. }
  5378. return
  5379. }
  5380.  
  5381.  
  5382. proc BWidget::SetFocusGrab {grab {focus {}}} {
  5383. variable _focusGrab
  5384. set index "$grab,$focus"
  5385.  
  5386. lappend _focusGrab($index) [::focus]
  5387. set oldGrab [::grab current $grab]
  5388. lappend _focusGrab($index) $oldGrab
  5389. if {[winfo exists $oldGrab]} {
  5390. lappend _focusGrab($index) [::grab status $oldGrab]
  5391. }
  5392. catch {::grab $grab}
  5393. if {[winfo exists $focus]} {
  5394. ::focus $focus
  5395. }
  5396. }
  5397.  
  5398. proc BWidget::RestoreFocusGrab {grab focus {destroy destroy}} {
  5399. variable _focusGrab
  5400. set index "$grab,$focus"
  5401. if {[info exists _focusGrab($index)]} {
  5402. foreach {oldFocus oldGrab oldStatus} $_focusGrab($index) break
  5403. unset _focusGrab($index)
  5404. } else {
  5405. set oldGrab ""
  5406. }
  5407.  
  5408. catch {::focus $oldFocus}
  5409. ::grab release $grab
  5410. if {[string equal $destroy "withdraw"]} {
  5411. wm withdraw $grab
  5412. } else {
  5413. ::destroy $grab
  5414. }
  5415. if {[winfo exists $oldGrab] && [winfo ismapped $oldGrab]} {
  5416. if {[string equal $oldStatus "global"]} {
  5417. ::grab -global $oldGrab
  5418. } else {
  5419. ::grab $oldGrab
  5420. }
  5421. }
  5422. }
  5423.  
  5424. proc BWidget::badOptionString { type value list } {
  5425. set list [lsort $list]
  5426.  
  5427. set x [lsearch -exact $list "--"]
  5428. if {$x > -1} {
  5429. set list [lreplace $list $x $x]
  5430. lappend list --
  5431. }
  5432.  
  5433. set last [lindex $list end]
  5434. set list [lreplace $list end end]
  5435. set msg  "bad $type \"$value\": must be "
  5436.  
  5437. if {![llength $list]} {
  5438. append msg "$last"
  5439. } elseif {[llength $list] == 1} {
  5440. append msg "$list or $last"
  5441. } else {
  5442. append msg "[join $list ", "], or $last"
  5443. }
  5444.  
  5445. return $msg
  5446. }
  5447.  
  5448.  
  5449. proc BWidget::wrongNumArgsString { string } {
  5450. return "wrong # args: should be \"$string\""
  5451. }
  5452.  
  5453.  
  5454. proc BWidget::read_file { file } {
  5455. set fp [open $file]
  5456. set x  [read $fp [file size $file]]
  5457. close $fp
  5458. return $x
  5459. }
  5460.  
  5461.  
  5462. proc BWidget::classes { class } {
  5463. variable use
  5464.  
  5465. ${class}::use
  5466. set classes [list $class]
  5467. if {![info exists use($class)]} { return }
  5468. foreach class $use($class) {
  5469. eval lappend classes [classes $class]
  5470. }
  5471. return [lsort -unique $classes]
  5472. }
  5473.  
  5474.  
  5475. proc BWidget::library { args } {
  5476. variable use
  5477.  
  5478. set exclude [list]
  5479. if {[set x [lsearch -exact $args "-exclude"]] > -1} {
  5480. set exclude [lindex $args [expr {$x + 1}]]
  5481. set args    [lreplace $args $x [expr {$x + 1}]]
  5482. }
  5483.  
  5484. set libs    [list widget init utils]
  5485. set classes [list]
  5486. foreach class $args {
  5487. ${class}::use
  5488. foreach c [classes $class] {
  5489. if {[lsearch -exact $exclude $c] > -1} { continue }
  5490. lappend classes $c
  5491. }
  5492. }
  5493.  
  5494. eval lappend libs [lsort -unique $classes]
  5495.  
  5496. set library ""
  5497. foreach lib $libs {
  5498. if {![info exists use($lib,file)]} {
  5499. set file [file join $::BWIDGET::LIBRARY $lib.tcl]
  5500. } else {
  5501. set file [file join $::BWIDGET::LIBRARY $use($lib,file).tcl]
  5502. }
  5503. append library [read_file $file]
  5504. }
  5505.  
  5506. return $library
  5507. }
  5508.  
  5509.  
  5510. proc BWidget::inuse { class } {
  5511. variable ::Widget::_inuse
  5512.  
  5513. if {![info exists _inuse($class)]} { return 0 }
  5514. return [expr $_inuse($class) > 0]
  5515. }
  5516.  
  5517.  
  5518. proc BWidget::write { filename {mode w} } {
  5519. variable use
  5520.  
  5521. if {![info exists use(classes)]} { return }
  5522.  
  5523. set classes [list]
  5524. foreach class $use(classes) {
  5525. if {![inuse $class]} { continue }
  5526. lappend classes $class
  5527. }
  5528.  
  5529. set fp [open $filename $mode]
  5530. puts $fp [eval library $classes]
  5531. close $fp
  5532.  
  5533. return
  5534. }
  5535.  
  5536.  
  5537. proc BWidget::bindMouseWheel { widgetOrClass } {
  5538. bind $widgetOrClass <MouseWheel>         {
  5539. if {![string equal [%W yview] "0 1"]} {
  5540. %W yview scroll [expr {-%D/24}]  units
  5541. }
  5542. }
  5543.  
  5544. bind $widgetOrClass <Shift-MouseWheel>   {
  5545. if {![string equal [%W yview] "0 1"]} {
  5546. %W yview scroll [expr {-%D/120}] pages
  5547. }
  5548. }
  5549.  
  5550. bind $widgetOrClass <Control-MouseWheel> {
  5551. if {![string equal [%W yview] "0 1"]} {
  5552. %W yview scroll [expr {-%D/120}] units
  5553. }
  5554. }
  5555.  
  5556. bind $widgetOrClass <Button-4> {event generate %W <MouseWheel> -delta  120}
  5557. bind $widgetOrClass <Button-5> {event generate %W <MouseWheel> -delta -120}
  5558. }
  5559.  
  5560.  
  5561. proc BWidget::Icon { name } {
  5562. return [$::BWidget::iconLibrary image $name]
  5563. }
  5564.  
  5565.  
  5566. proc BWidget::LoadBWidgetIconLibrary {} {
  5567. if {![Widget::exists $::BWidget::iconLibrary]} {
  5568. IconLibrary $::BWidget::iconLibrary -file $::BWidget::iconLibraryFile
  5569. }
  5570. }
  5571.  
  5572.  
  5573. proc BWidget::LoadBWidgetTreeIcons {} {
  5574. set dir [file join $::BWIDGET::LIBRARY images]
  5575. image create photo BWidget::plus  -file [file join $dir plus.gif]
  5576. image create photo BWidget::minus -file [file join $dir minus.gif]
  5577. }
  5578.  
  5579.  
  5580. proc BWidget::CreateImage { gifdata pngdata args } {
  5581. lappend args -format $::BWidget::imageFormat
  5582. if {[BWidget::using png]} {
  5583. lappend args -data $pngdata
  5584. } else {
  5585. lappend args -data $gifdata
  5586. }
  5587.  
  5588. return [eval image create photo $args]
  5589. }
  5590.  
  5591.  
  5592. proc BWidget::ParseArgs { _arrayName _arglist args } {
  5593. upvar 1 $_arrayName array
  5594.  
  5595. array set _args {
  5596. -strict     0
  5597. -options    ""
  5598. -switches   ""
  5599. -nocomplain 0
  5600. }
  5601. array set _args $args
  5602. if {[info exists _args(-errorvar)]} { upvar 1 $_args(-errorvar) error }
  5603.  
  5604. set options  $_args(-options)
  5605. set switches $_args(-switches)
  5606.  
  5607. foreach switch $switches {
  5608. set array([string range $switch 1 end]) 0
  5609. }
  5610.  
  5611. set array(OPTIONS)  [list]
  5612. set array(SWITCHES) [list]
  5613.  
  5614. set oplen   [llength $options]
  5615. set swlen   [llength $switches]
  5616. set index   0
  5617. set waiting 0
  5618. foreach arg $_arglist {
  5619. switch -glob -- $arg {
  5620. "--" {
  5621. incr index
  5622. break
  5623. }
  5624.  
  5625. "-*" {
  5626. if {$waiting} {
  5627. set waiting 0
  5628. set array($option) $arg
  5629. lappend array(OPTIONS) -$option $arg
  5630. } else {
  5631. if {$swlen && [lsearch -exact $switches $arg] > -1} {
  5632. lappend array(SWITCHES) $arg
  5633. set array([string range $arg 1 end]) 1
  5634. } elseif {$oplen && [lsearch -exact $options $arg] < 0} {
  5635. if {$_args(-nocomplain)} { return 0 }
  5636. return -code error "unknown option \"$arg\""
  5637. } elseif {$_args(-strict)} {
  5638. set switches [concat -- $_args(-switches)]
  5639. set msg [BWidget::badOptionString option $arg $switches]
  5640. return -code error $msg
  5641. } else {
  5642. set waiting 1
  5643. set option [string range $arg 1 end]
  5644. }
  5645. }
  5646. }
  5647.  
  5648. default {
  5649. if {$waiting} {
  5650. set waiting 0
  5651. set array($option) $arg
  5652. lappend array(OPTIONS) -$option $arg
  5653. } else {
  5654. break
  5655. }
  5656. }
  5657. }
  5658.  
  5659. incr index
  5660. }
  5661.  
  5662. set array(ARGS) [lrange $_arglist $index end]
  5663.  
  5664. return 1
  5665. }
  5666.  
  5667.  
  5668. proc BWidget::CopyBindings { from to } {
  5669. foreach event [bind $from] {
  5670. bind $to $event [bind $from $event]
  5671. }
  5672. }
  5673.  
  5674.  
  5675. proc BWidget::DrawCanvasBorder { canvas relief color coords args } {
  5676. lassign $coords x0 y0 x1 y1
  5677. lassign [BWidget::get3dcolor $canvas $color] dark light dark2 light2
  5678.  
  5679. switch -- $relief {
  5680. "raised" - "sunken" {
  5681. lappend lines [list $x0 $y1 $x0 $y0 $x1 $y0]
  5682. lappend lines [list $x1 $y0 $x1 $y1 $x0 $y1]
  5683. lappend lines [list  [expr {$x0 + 1}] [expr {$y1 - 2}]  [expr {$x0 + 1}] [expr {$y0 + 1}]  [expr {$x1 - 1}] [expr {$y0 + 1}]]
  5684. lappend lines [list  [expr {$x0 + 1}] [expr {$y1 - 1}]  [expr {$x1 - 1}] [expr {$y1 - 1}]  [expr {$x1 - 1}] $y0]
  5685.  
  5686. set colors [list $light $dark $light2 $dark2]
  5687. if {[string equal $relief "sunken"]} {
  5688. set colors [list $dark $light $dark2 $light2]
  5689. }
  5690. }
  5691.  
  5692. "groove" - "ridge" {
  5693. lappend lines [list  $x0 $y1  $x1 $y1  $x1 $y0  $x1 [expr {$y0 + 1}]  [expr {$x0 + 1}] [expr {$y0 + 1}]  [expr {$x0 + 1}] $y1  ]
  5694.  
  5695. lappend lines [list  $x0 $y0  [expr {$x1 - 1}] $y0  [expr {$x1 - 1}] [expr {$y1 - 1}]  $x0 [expr {$y1 - 1}]  $x0 $y0  ]
  5696.  
  5697. set colors [list $light $dark2]
  5698. if {[string equal $relief "ridge"]} {
  5699. set colors [list $dark2 $light]
  5700. }
  5701. }
  5702.  
  5703. "rounded" {
  5704. set coords [list  [expr {$x0 + 1}] $y0  [expr {$x1 - 1}] $y0  $x1 [expr {$y0 + 1}]  $x1 [expr {$y1 - 1}]  [expr {$x1 - 1}] $y1  [expr {$x0 + 1}] $y1  $x0 [expr {$y1 - 1}]  $x0 [expr {$y0 + 1}]  [expr {$x0 + 1}] $y0  ]
  5705.  
  5706. set opts [list -outline $dark2 -fill $color]
  5707. eval [list $canvas create poly $coords] $opts $args
  5708.  
  5709. return
  5710. }
  5711.  
  5712. "highlight" {
  5713. set opts [list -outline $dark -fill $light]
  5714. eval [list $canvas create rect $coords] $opts $args
  5715.  
  5716. set coords [list [incr x0] [incr y0] [incr x1 -1] [incr y1 -1]]
  5717. eval [list $canvas create rect $coords -outline $dark2] $args
  5718.  
  5719. return
  5720. }
  5721. }
  5722.  
  5723. foreach line $lines color $colors {
  5724. eval [list $canvas create line $line -fill $color] $args
  5725. }
  5726. }
  5727.  
  5728.  
  5729. if {[info exists ::InstallJammer]} { return }
  5730.  
  5731. namespace eval ::BWIDGET {
  5732. variable LIBRARY [file join $::installkit::root lib InstallJammer]
  5733. }
  5734.  
  5735. proc BWidgetInit {} {
  5736. BWidget::use ttk 1 -force
  5737.  
  5738. image create photo treeplus -data {R0lGODlhCQAJAPcAAAAAAIAAAACAAICAAAAAgIAAgACAgICAgMDAwP8AAAD/AP//AAAA//8A/wD//////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwAAZgAAmQAAzAAA/wAzAAAzMwAzZgAzmQAzzAAz/wBmAABmMwBmZgBmmQBmzABm/wCZAACZMwCZZgCZmQCZzACZ/wDMAADMMwDMZgDMmQDMzADM/wD/AAD/MwD/ZgD/mQD/zAD//zMAADMAMzMAZjMAmTMAzDMA/zMzADMzMzMzZjMzmTMzzDMz/zNmADNmMzNmZjNmmTNmzDNm/zOZADOZMzOZZjOZmTOZzDOZ/zPMADPMMzPMZjPMmTPMzDPM/zP/ADP/MzP/ZjP/mTP/zDP//2YAAGYAM2YAZmYAmWYAzGYA/2YzAGYzM2YzZmYzmWYzzGYz/2ZmAGZmM2ZmZmZmmWZmzGZm/2aZAGaZM2aZZmaZmWaZzGaZ/2bMAGbMM2bMZmbMmWbMzGbM/2b/AGb/M2b/Zmb/mWb/zGb//5kAAJkAM5kAZpkAmZkAzJkA/5kzAJkzM5kzZpkzmZkzzJkz/5lmAJlmM5lmZplmmZlmzJlm/5mZAJmZM5mZZpmZmZmZzJmZ/5nMAJnMM5nMZpnMmZnMzJnM/5n/AJn/M5n/Zpn/mZn/zJn//8wAAMwAM8wAZswAmcwAzMwA/8wzAMwzM8wzZswzmcwzzMwz/8xmAMxmM8xmZsxmmcxmzMxm/8yZAMyZM8yZZsyZmcyZzMyZ/8zMAMzMM8zMZszMmczMzMzM/8z/AMz/M8z/Zsz/mcz/zMz///8AAP8AM/8AZv8Amf8AzP8A//8zAP8zM/8zZv8zmf8zzP8z//9mAP9mM/9mZv9mmf9mzP9m//+ZAP+ZM/+ZZv+Zmf+ZzP+Z///MAP/MM//MZv/Mmf/MzP/M////AP//M///Zv//mf//zP///ywAAAAACQAJAAAINgARGBpI0JDABwgTPhiYEEBChggdPqDGEIBFixQNIfQHwB+1jB+pAQg5kBoCBNNSChRYcCCCgAA7}
  5739.  
  5740. image create photo treeminus -data {R0lGODlhCQAJAPcAAAAAAIAAAACAAICAAAAAgIAAgACAgICAgMDAwP8AAAD/AP//AAAA//8A/wD//////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwAAZgAAmQAAzAAA/wAzAAAzMwAzZgAzmQAzzAAz/wBmAABmMwBmZgBmmQBmzABm/wCZAACZMwCZZgCZmQCZzACZ/wDMAADMMwDMZgDMmQDMzADM/wD/AAD/MwD/ZgD/mQD/zAD//zMAADMAMzMAZjMAmTMAzDMA/zMzADMzMzMzZjMzmTMzzDMz/zNmADNmMzNmZjNmmTNmzDNm/zOZADOZMzOZZjOZmTOZzDOZ/zPMADPMMzPMZjPMmTPMzDPM/zP/ADP/MzP/ZjP/mTP/zDP//2YAAGYAM2YAZmYAmWYAzGYA/2YzAGYzM2YzZmYzmWYzzGYz/2ZmAGZmM2ZmZmZmmWZmzGZm/2aZAGaZM2aZZmaZmWaZzGaZ/2bMAGbMM2bMZmbMmWbMzGbM/2b/AGb/M2b/Zmb/mWb/zGb//5kAAJkAM5kAZpkAmZkAzJkA/5kzAJkzM5kzZpkzmZkzzJkz/5lmAJlmM5lmZplmmZlmzJlm/5mZAJmZM5mZZpmZmZmZzJmZ/5nMAJnMM5nMZpnMmZnMzJnM/5n/AJn/M5n/Zpn/mZn/zJn//8wAAMwAM8wAZswAmcwAzMwA/8wzAMwzM8wzZswzmcwzzMwz/8xmAMxmM8xmZsxmmcxmzMxm/8yZAMyZM8yZZsyZmcyZzMyZ/8zMAMzMM8zMZszMmczMzMzM/8z/AMz/M8z/Zsz/mcz/zMz///8AAP8AM/8AZv8Amf8AzP8A//8zAP8zM/8zZv8zmf8zzP8z//9mAP9mM/9mZv9mmf9mzP9m//+ZAP+ZM/+ZZv+Zmf+ZzP+Z///MAP/MM//MZv/Mmf/MzP/M////AP//M///Zv//mf//zP///yH5BAEAABAALAAAAAAJAAkAAAhHAGGlMmQoVaFChmAZ+sew4T9VqRwyzEfw3zaL+fxVQ+gPhUeP/lSp8rct4zZt1DhSo4YP5bSC1KZNczZzWiGFqgwBGphKVUAAOw==}
  5741.  
  5742. image create photo checkon -data {R0lGODlhEAAQAAAAACwAAAAAEAAQAIAAAAD///8CK4yPacDtfZ5kEaiKlaXLJsoFYLV5Ynl6IehkZ2e+XfSZoWZPD6nf1w9UFAAAOw==}
  5743.  
  5744. image create photo checkoff -data {R0lGODlhEAAQAAAAACwAAAAAEAAQAIAAAAD///8CJYyPacDtfZ5kEaiKb6DLar55FwgqpGiKZXJqYTaq01PNkIvnRwEAOw==}
  5745.  
  5746. set ::BWidget::iconLibraryFile [file join $::BWIDGET::LIBRARY icons.tkico]
  5747.  
  5748. option add *Tree.background         white       widgetDefault
  5749. option add *Tree.crossopenimage     treeminus   widgetDefault
  5750. option add *Tree.crosscloseimage    treeplus    widgetDefault
  5751.  
  5752. if {$::tcl_platform(platform) ne "windows"} {
  5753. option add *font                TkTextFont
  5754. option add *background          [style default . -background]
  5755. option add *selectForeground    [style default . -selectforeground]
  5756. option add *selectBackground    [style default . -selectbackground]
  5757.  
  5758. option add *Listbox.background  white
  5759.  
  5760. option add *Entry.background    white
  5761. option add *Entry.borderWidth   1
  5762.  
  5763. option add *Text.background     white
  5764. }
  5765. }
  5766.  
  5767. namespace eval DragSite    { proc use {} {} }
  5768. namespace eval DropSite    { proc use {} {} }
  5769. namespace eval DynamicHelp { proc use {} {} }
  5770.  
  5771. proc DragSite::include { class type event } {
  5772. set dragoptions [list  [list    -dragenabled    Boolean    0    0]  [list    -draginitcmd    String    ""    0]  [list    -dragendcmd    String    ""    0]  [list    -dragtype    String    $type    0]  [list    -dragevent    Enum    $event    0    [list 1 2 3]]  ]
  5773. Widget::declare $class $dragoptions
  5774. }
  5775. proc DragSite::setdrag {args} { }
  5776.  
  5777. proc DropSite::include { class types } {
  5778. set dropoptions [list  [list    -dropenabled    Boolean    0    0]  [list    -dropovercmd    String    ""    0]  [list    -dropcmd    String    ""    0]  [list    -droptypes    String    $types    0]  ]
  5779. Widget::declare $class $dropoptions
  5780. }
  5781.  
  5782. proc DynamicHelp::include { class type } {
  5783. set helpoptions [list  [list -helptext String "" 0]  [list -helpvar  String "" 0]  [list -helptype Enum $type 0 [list balloon variable]]  ]
  5784. Widget::declare $class $helpoptions
  5785. }
  5786.  
  5787. proc DropSite::setdrop    { args } { }
  5788. proc DropSite::setcursor  { args } { }
  5789. proc DynamicHelp::sethelp { args } { }
  5790.  
  5791. package provide BWidget 1.8
  5792.  
  5793. BWidgetInit
  5794. if {[string equal $::tcl_platform(platform) "windows"]} {
  5795. option add *ListBox.background      SystemWindow            widgetDefault
  5796. option add *ButtonBox.padY          0                       widgetDefault
  5797. option add *Dialog.padY             0                       widgetDefault
  5798. } else {
  5799. option add *Scrollbar.width         12                      widgetDefault
  5800. option add *Scrollbar.borderWidth   1                       widgetDefault
  5801. option add *Dialog.separator        1                       widgetDefault
  5802. option add *MainFrame.relief        raised                  widgetDefault
  5803. option add *MainFrame.separator     none                    widgetDefault
  5804. option add *MessageDlg.usenative    0                       widgetDefault
  5805. }
  5806.  
  5807. option read [file join $::BWIDGET::LIBRARY lang en.rc]
  5808.  
  5809. bind Entry   <<TraverseIn>> { %W selection range 0 end; %W icursor end }
  5810. bind Spinbox <<TraverseIn>> { %W selection range 0 end; %W icursor end }
  5811.  
  5812. bind all <Key-Tab>       { Widget::traverseTo [Widget::focusNext %W] }
  5813. bind all <<PrevWindow>>  { Widget::traverseTo [Widget::focusPrev %W] }
  5814.  
  5815. namespace eval ::BWidget {
  5816. variable library     $::BWIDGET::LIBRARY
  5817. variable langDir     [file join $library lang]
  5818. variable imageDir    [file join $library images]
  5819. variable imageFormat GIF
  5820.  
  5821. variable iconLibrary
  5822. if {![info exists iconLibrary]} {
  5823. set iconLibrary BWidgetIcons
  5824. }
  5825.  
  5826. variable iconLibraryFile
  5827. if {![info exists iconLibraryFile]} {
  5828. set iconLibraryFile [file join $imageDir BWidget.gif.tkico]
  5829. }
  5830.  
  5831. variable colors
  5832. if {[string equal $::tcl_platform(platform) "windows"]} {
  5833. array set colors {
  5834. SystemButtonFace    SystemButtonFace
  5835. SystemButtonText    SystemButtonText
  5836. SystemDisabledText  SystemDisabledText
  5837. SystemHighlight     SystemHighlight
  5838. SystemHighlightText SystemHighlightText
  5839. SystemMenu          SystemMenu
  5840. SystemMenuText      SystemMenuText
  5841. SystemScrollbar     SystemScrollbar
  5842. SystemWindow        SystemWindow
  5843. SystemWindowFrame   SystemWindowFrame
  5844. SystemWindowText    SystemWindowText
  5845. }
  5846. } else {
  5847. array set colors {
  5848. SystemButtonFace    #d9d9d9
  5849. SystemButtonText    black
  5850. SystemDisabledText  #a3a3a3
  5851. SystemHighlight     #c3c3c3
  5852. SystemHighlightText white
  5853. SystemMenu          #d9d9d9
  5854. SystemMenuText      white
  5855. SystemScrollbar     #d9d9d9
  5856. SystemWindow        white
  5857. SystemWindowFrame   #d9d9d9
  5858. SystemWindowText    black
  5859. }
  5860. }
  5861.  
  5862. if {[lsearch -exact [font names] "TkTextFont"] < 0} {
  5863. catch {font create TkTextFont}
  5864. catch {font create TkDefaultFont}
  5865. catch {font create TkHeadingFont}
  5866. catch {font create TkCaptionFont}
  5867. catch {font create TkTooltipFont}
  5868.  
  5869. switch -- [tk windowingsystem] {
  5870. win32 {
  5871. if {$::tcl_platform(osVersion) >= 5.0} {
  5872. variable family "Tahoma"
  5873. } else {
  5874. variable family "MS Sans Serif"
  5875. }
  5876. variable size 8
  5877.  
  5878. font configure TkDefaultFont -family $family -size $size
  5879. font configure TkTextFont    -family $family -size $size
  5880. font configure TkHeadingFont -family $family -size $size
  5881. font configure TkCaptionFont -family $family -size $size  -weight bold
  5882. font configure TkTooltipFont -family $family -size $size
  5883. }
  5884.  
  5885. classic - aqua {
  5886. variable family "Lucida Grande"
  5887. variable size 13
  5888. variable viewsize 12
  5889. variable smallsize 11
  5890.  
  5891. font configure TkDefaultFont -family $family -size $size
  5892. font configure TkTextFont    -family $family -size $size
  5893. font configure TkHeadingFont -family $family -size $smallsize
  5894. font configure TkCaptionFont -family $family -size $size  -weight bold
  5895. font configure TkTooltipFont -family $family -size $viewsize
  5896. }
  5897.  
  5898. x11 {
  5899. if {![catch {tk::pkgconfig get fontsystem} fs]
  5900. && [string equal $fs "xft"]} {
  5901. variable family "sans-serif"
  5902. } else {
  5903. variable family "Helvetica"
  5904. }
  5905. variable size -12
  5906. variable ttsize -10
  5907. variable capsize -14
  5908.  
  5909. font configure TkDefaultFont -family $family -size $size
  5910. font configure TkTextFont    -family $family -size $size
  5911. font configure TkHeadingFont -family $family -size $size  -weight bold
  5912. font configure TkCaptionFont -family $family -size $capsize  -weight bold
  5913. font configure TkTooltipFont -family $family -size $ttsize
  5914. }
  5915. }
  5916. }
  5917. } ; ## namespace eval ::BWidget
  5918.  
  5919.  
  5920. namespace eval Label {
  5921. Widget::define Label label DragSite DropSite DynamicHelp
  5922.  
  5923. Widget::tkinclude Label label .l  remove { -foreground -state -text -textvariable -underline }
  5924.  
  5925. Widget::declare Label {
  5926. {-name               String     ""     0}
  5927. {-text               String     ""     0}
  5928. {-textvariable       String     ""     0}
  5929. {-underline          Int        -1     0 "%d >= -1"}
  5930. {-focus              String     ""     0}
  5931. {-foreground         Color      "SystemButtonText"       0}
  5932. {-disabledforeground Color      "SystemDisabledText"     0}
  5933. {-state              Enum       normal 0  {normal disabled}}
  5934.  
  5935. {-autowrap           Boolean    "0"    1}
  5936. {-wrappadx           Int        "10"   0}
  5937.  
  5938. {-elide              Boolean    "0"    1}
  5939. {-ellipsis           String     "..."  0}
  5940. {-elidepadx          Int        "5"    0}
  5941. {-elideside          Enum       "right" 0 {center left right}}
  5942.  
  5943. {-fg                 Synonym    -foreground}
  5944. }
  5945.  
  5946. DynamicHelp::include Label balloon
  5947. DragSite::include    Label "" 1
  5948. DropSite::include    Label {
  5949. TEXT    {move {}}
  5950. IMAGE   {move {}}
  5951. BITMAP  {move {}}
  5952. FGCOLOR {move {}}
  5953. BGCOLOR {move {}}
  5954. COLOR   {move {}}
  5955. }
  5956.  
  5957. Widget::syncoptions Label "" .l {-text {} -underline {}}
  5958.  
  5959. bind BwLabel <FocusIn>   [list Label::setfocus %W]
  5960. bind BwLabel <Destroy>   [list Label::_destroy %W]
  5961. }
  5962.  
  5963.  
  5964. proc Label::create { path args } {
  5965. Widget::initArgs Label $args maps
  5966.  
  5967. frame $path -class Label -borderwidth 0 -highlightthickness 0 -relief flat
  5968. Widget::initFromODB Label $path $maps(Label)
  5969.  
  5970. Widget::getVariable $path data
  5971.  
  5972. set data(width) 0
  5973.  
  5974. eval [list label $path.l] $maps(.l)
  5975.  
  5976. if {[string equal [Widget::cget $path -state] "normal"]} {
  5977. set fg [Widget::cget $path -foreground]
  5978. } else {
  5979. set fg [Widget::cget $path -disabledforeground]
  5980. }
  5981.  
  5982. set var [Widget::cget $path -textvariable]
  5983. if {$var == ""
  5984. && [Widget::cget $path -image] == ""
  5985. && [Widget::cget $path -bitmap] == ""} {
  5986. set desc [BWidget::getname [Widget::cget $path -name]]
  5987. if {[string length $desc]} {
  5988. set text  [lindex $desc 0]
  5989. set under [lindex $desc 1]
  5990. } else {
  5991. set text  [Widget::cget $path -text]
  5992. set under [Widget::cget $path -underline]
  5993. }
  5994. } else {
  5995. set under -1
  5996. set text  ""
  5997. }
  5998.  
  5999. $path.l configure -text $text -underline $under -foreground $fg
  6000.  
  6001. set accel [string tolower [string index $text $under]]
  6002. if {[string length $accel]} {
  6003. bind [winfo toplevel $path] <Alt-$accel> [list Label::setfocus $path]
  6004. }
  6005.  
  6006. bindtags $path   [list BwLabel [winfo toplevel $path] all]
  6007. bindtags $path.l [list $path.l $path Label [winfo toplevel $path] all]
  6008. pack $path.l -expand yes -fill both
  6009.  
  6010. set dragendcmd [Widget::cget $path -dragendcmd]
  6011. DragSite::setdrag $path $path.l Label::_init_drag_cmd $dragendcmd 1
  6012. DropSite::setdrop $path $path.l Label::_over_cmd Label::_drop_cmd 1
  6013. DynamicHelp::sethelp $path $path.l 1
  6014.  
  6015. if {[string length $var]} {
  6016. upvar #0 $var textvar
  6017. _trace_variable $path
  6018. if {![info exists textvar]} {
  6019. set textvar [Widget::getoption $path -text]
  6020. } else {
  6021. _update_textvariable $path "" "" write
  6022. }
  6023. }
  6024.  
  6025. if {[Widget::getoption $path -elide]
  6026. || [Widget::getoption $path -autowrap]} {
  6027. bind $path.l <Configure> [list Label::_redraw $path %w]
  6028. }
  6029.  
  6030. return [Widget::create Label $path]
  6031. }
  6032.  
  6033.  
  6034. proc Label::configure { path args } {
  6035. set oldunder [$path.l cget -underline]
  6036. if {$oldunder != -1} {
  6037. set oldaccel [string index [$path.l cget -text] $oldunder]
  6038. set oldaccel [string tolower $oldaccel]
  6039. } else {
  6040. set oldaccel ""
  6041. }
  6042.  
  6043. set oldvar [$path.l cget -textvariable]
  6044.  
  6045. set res [Widget::configure $path $args]
  6046.  
  6047. set cfg  [Widget::hasChanged $path -foreground fg]
  6048. set cdfg [Widget::hasChanged $path -disabledforeground dfg]
  6049. set cst  [Widget::hasChanged $path -state state]
  6050.  
  6051. if { $cst || $cfg || $cdfg } {
  6052. if { $state == "normal" } {
  6053. $path.l configure -fg $fg
  6054. } else {
  6055. $path.l configure -fg $dfg
  6056. }
  6057. }
  6058.  
  6059. set cv [Widget::hasChanged $path -textvariable var]
  6060. set cb [Widget::hasChanged $path -image img]
  6061. set ci [Widget::hasChanged $path -bitmap bmp]
  6062. set cn [Widget::hasChanged $path -name name]
  6063. set ct [Widget::hasChanged $path -text text]
  6064. set cu [Widget::hasChanged $path -underline under]
  6065.  
  6066. if { $cv || $cb || $ci || $cn || $ct || $cu } {
  6067. if {  $var == "" && $img == "" && $bmp == "" } {
  6068. set desc [BWidget::getname $name]
  6069. if { $desc != "" } {
  6070. set text  [lindex $desc 0]
  6071. set under [lindex $desc 1]
  6072. }
  6073. } else {
  6074. set under -1
  6075. set text  ""
  6076. }
  6077. set top [winfo toplevel $path]
  6078. if { $oldaccel != "" } {
  6079. bind $top <Alt-$oldaccel> {}
  6080. }
  6081. set accel [string tolower [string index $text $under]]
  6082. if { $accel != "" } {
  6083. bind $top <Alt-$accel> [list Label::setfocus $path]
  6084. }
  6085. $path.l configure -text $text -underline $under -textvariable $var
  6086. }
  6087.  
  6088. if {$cv} {
  6089. if {[string length $oldvar]} {
  6090. trace remove variable $oldvar [list write unset]  [list Label::_update_textvariable $path]
  6091. }
  6092.  
  6093. _trace_variable $path
  6094. }
  6095.  
  6096. if {$ct && [Widget::getoption $path -elide]} {
  6097. _redraw $path [winfo width $path]
  6098. }
  6099.  
  6100. set force [Widget::hasChanged $path -dragendcmd dragend]
  6101. DragSite::setdrag $path $path.l Label::_init_drag_cmd $dragend $force
  6102. DropSite::setdrop $path $path.l Label::_over_cmd Label::_drop_cmd
  6103. DynamicHelp::sethelp $path $path.l
  6104.  
  6105. return $res
  6106. }
  6107.  
  6108.  
  6109. proc Label::cget { path option } {
  6110. return [Widget::cget $path $option]
  6111. }
  6112.  
  6113.  
  6114. proc Label::setfocus { path } {
  6115. if {[string equal [Widget::cget $path -state] "normal"]} {
  6116. set w [Widget::cget $path -focus]
  6117. if { [winfo exists $w] && [Widget::focusOK $w] } {
  6118. focus $w
  6119. }
  6120. }
  6121. }
  6122.  
  6123.  
  6124. proc Label::_init_drag_cmd { path X Y top } {
  6125. set path [winfo parent $path]
  6126. if {[set cmd [Widget::cget $path -draginitcmd]] != ""} {
  6127. return [uplevel \#0 $cmd [list $path $X $Y $top]]
  6128. }
  6129. if { [set data [$path.l cget -image]] != "" } {
  6130. set type "IMAGE"
  6131. pack [label $top.l -image $data]
  6132. } elseif { [set data [$path.l cget -bitmap]] != "" } {
  6133. set type "BITMAP"
  6134. pack [label $top.l -bitmap $data]
  6135. } else {
  6136. set data [$path.l cget -text]
  6137. set type "TEXT"
  6138. }
  6139. set usertype [Widget::getoption $path -dragtype]
  6140. if { $usertype != "" } {
  6141. set type $usertype
  6142. }
  6143. return [list $type {copy} $data]
  6144. }
  6145.  
  6146.  
  6147. proc Label::_drop_cmd { path source X Y op type data } {
  6148. set path [winfo parent $path]
  6149. if {[set cmd [Widget::cget $path -dropcmd]] != ""} {
  6150. return [uplevel \#0 $cmd [list $path $source $X $Y $op $type $data]]
  6151. }
  6152. if { $type == "COLOR" || $type == "FGCOLOR" } {
  6153. configure $path -foreground $data
  6154. } elseif { $type == "BGCOLOR" } {
  6155. configure $path -background $data
  6156. } else {
  6157. set text   ""
  6158. set image  ""
  6159. set bitmap ""
  6160. switch -- $type {
  6161. IMAGE   {set image $data}
  6162. BITMAP  {set bitmap $data}
  6163. default {
  6164. set text $data
  6165. if { [set var [$path.l cget -textvariable]] != "" } {
  6166. configure $path -image "" -bitmap ""
  6167. BWidget::setglobal $var $data
  6168. return
  6169. }
  6170. }
  6171. }
  6172. configure $path -text $text -image $image -bitmap $bitmap
  6173. }
  6174. return 1
  6175. }
  6176.  
  6177.  
  6178. proc Label::_over_cmd { path source event X Y op type data } {
  6179. set path [winfo parent $path]
  6180. if { [set cmd [Widget::cget $path -dropovercmd]] != "" } {
  6181. set opts [list $path $source $event $X $Y $op $type $data]
  6182. return [uplevel \#0 $cmd $opts]
  6183. }
  6184. if {[Widget::getoption $path -state] == "normal" ||
  6185. $type == "COLOR" || $type == "FGCOLOR" || $type == "BGCOLOR"} {
  6186. DropSite::setcursor based_arrow_down
  6187. return 1
  6188. }
  6189. DropSite::setcursor dot
  6190. return 0
  6191. }
  6192.  
  6193.  
  6194. proc Label::_redraw { path width } {
  6195. Widget::getVariable $path data
  6196.  
  6197. if {$width == $data(width)} { return }
  6198.  
  6199. if {[Widget::getoption $path -autowrap]} {
  6200. set padx [Widget::getoption $path -wrappadx]
  6201. $path.l configure -wraplength [expr {$width - $padx}]
  6202. } elseif {[Widget::getoption $path -elide]} {
  6203. set font     [$path.l cget -font]
  6204. set text     [Widget::getoption $path -text]
  6205. set side     [Widget::getoption $path -elideside]
  6206. set ellipsis [Widget::getoption $path -ellipsis]
  6207.  
  6208. set bd    [$path.l cget -bd]
  6209. set padx  [$path.l cget -padx]
  6210. set epadx [Widget::getoption $path -elidepadx]
  6211. set width [expr {($width - (($bd + $padx) * 2)) - $epadx}]
  6212.  
  6213. if {$width > 0} {
  6214. set string $text
  6215. while {[font measure $font $string] > $width} {
  6216. switch -- $side {
  6217. "left"   {
  6218. set text   [string range $text 1 end]
  6219. set string $ellipsis$text
  6220. }
  6221.  
  6222. "right"  {
  6223. set text   [string range $text 0 end-1]
  6224. set string $text$ellipsis
  6225. }
  6226.  
  6227. "center" {
  6228. set x [expr {[string length $text] / 2}]
  6229. set l [string range $text 0 $x]
  6230. set r [string range $text [incr x 2] end]
  6231. set text   $l$r
  6232. set string $l$ellipsis$r
  6233. }
  6234. }
  6235.  
  6236. if {![string length $text]} { break }
  6237. }
  6238.  
  6239. $path.l configure -text $string
  6240. }
  6241. }
  6242.  
  6243. set data(width) [winfo reqwidth $path.l]
  6244. }
  6245.  
  6246.  
  6247. proc Label::_trace_variable { path } {
  6248. set varName [Widget::getoption $path -textvariable]
  6249.  
  6250. if {[string length $varName]} {
  6251. set ops     [list write unset]
  6252. set command [list Label::_update_textvariable $path]
  6253.  
  6254. uplevel #0 [list trace add variable $varName $ops $command]
  6255. }
  6256. }
  6257.  
  6258.  
  6259. proc Label::_update_textvariable { path name1 name2 op } {
  6260. set varName [Widget::getoption $path -textvariable]
  6261. upvar #0 $varName var
  6262.  
  6263. switch -- $op {
  6264. "write" {
  6265. Widget::setoption $path -text $var
  6266.  
  6267. $path.l configure -text $var
  6268.  
  6269. _redraw $path [winfo width $path]
  6270. }
  6271.  
  6272. "unset" {
  6273. set var [Widget::getoption $path -text]
  6274. _trace_variable $path
  6275. }
  6276. }
  6277. }
  6278.  
  6279.  
  6280. proc Label::_destroy { path } {
  6281. set ops     [list write unset]
  6282. set cmd     [list Label::_update_textvariable $path]
  6283. set varName [Widget::getoption $path -textvariable]
  6284.  
  6285. uplevel #0 [list trace remove variable $varName $ops $cmd]
  6286.  
  6287. Widget::destroy $path
  6288. }
  6289.  
  6290.  
  6291. namespace eval Tree {
  6292. Widget::define Tree tree DragSite DropSite DynamicHelp
  6293.  
  6294. namespace eval Node {
  6295. Widget::declare Tree::Node {
  6296. {-text       String     ""      0}
  6297. {-font       String     ""      0}
  6298. {-image      String     ""      0}
  6299. {-window     String     ""      0}
  6300. {-fill       Color      "SystemButtonText"   0}
  6301. {-data       String     ""      0}
  6302. {-open       Boolean    0       0}
  6303. {-selectable Boolean    1       0}
  6304. {-drawcross  Enum       auto    0 {auto allways never}}
  6305. {-padx       Int        -1      0 "%d >= -1"}
  6306. {-deltax     Int        -1      0 "%d >= -1"}
  6307. {-anchor     String     "w"     0 ""}
  6308. }
  6309. }
  6310.  
  6311. DynamicHelp::include Tree::Node balloon
  6312.  
  6313. Widget::tkinclude Tree canvas .c  remove {
  6314. -insertwidth -insertbackground -insertborderwidth -insertofftime
  6315. -insertontime -selectborderwidth -closeenough -confine -scrollregion
  6316. -xscrollincrement -yscrollincrement -width -height
  6317. } initialize {
  6318. -background white -relief sunken -borderwidth 2
  6319. -takefocus 1 -highlightthickness 1 -width 200
  6320. }
  6321.  
  6322. DragSite::include Tree "TREE_NODE" 1
  6323. DropSite::include Tree {
  6324. TREE_NODE {copy {} move {}}
  6325. }
  6326.  
  6327. Widget::declare Tree {
  6328. {-deltax            Int        10       0 "%d >= 0"}
  6329. {-deltay            Int        15       0 "%d >= 0"}
  6330. {-padx              Int        20       0 "%d >= 0"}
  6331. {-font              String     "TkTextFont" 0}
  6332. {-background        Color      "SystemWindow"  0}
  6333. {-selectbackground  Color      "SystemHighlight"  0}
  6334. {-selectforeground  Color      "SystemHighlightText" 0}
  6335. {-selectcommand     String     ""       0}
  6336. {-width             TkResource ""       0 listbox}
  6337. {-height            TkResource ""       0 listbox}
  6338. {-selectfill        Boolean    0        0}
  6339. {-showlines         Boolean    1        0}
  6340. {-linesfill         Color      "SystemButtonText"  0}
  6341. {-linestipple       TkResource ""       0 {label -bitmap}}
  6342. {-crossfill         Color      "SystemButtonText"  0}
  6343. {-redraw            Boolean    1        0}
  6344. {-opencmd           String     ""       0}
  6345. {-closecmd          String     ""       0}
  6346. {-dropovermode      Flag       "wpn"    0 "wpn"}
  6347. {-dropcmd           String     "Tree::_drag_and_drop" 0}
  6348.  
  6349. {-crossopenimage    String     ""       0}
  6350. {-crosscloseimage   String     ""       0}
  6351. {-crossopenbitmap   String     ""       0}
  6352. {-crossclosebitmap  String     ""       0}
  6353.  
  6354. {-bg                Synonym    -background}
  6355. }
  6356.  
  6357. Widget::addmap Tree "" .c { -deltay -yscrollincrement }
  6358.  
  6359. bind Tree <FocusIn>   [list after idle {BWidget::refocus %W %W.c}]
  6360. bind Tree <Destroy>   [list Tree::_destroy %W]
  6361. bind Tree <Configure> [list Tree::_update_scrollregion %W]
  6362.  
  6363. bind TreeSentinalStart <Button-1> {
  6364. if {$::Tree::sentinal(%W)} {
  6365. set ::Tree::sentinal(%W) 0
  6366. break
  6367. }
  6368. }
  6369.  
  6370. bind TreeSentinalEnd <Button-1> {
  6371. set ::Tree::sentinal(%W) 0
  6372. }
  6373.  
  6374. bind TreeFocus <Button-1> [list focus %W]
  6375.  
  6376. BWidget::bindMouseWheel TreeCanvas
  6377.  
  6378. variable _edit
  6379. set _edit(editing) 0
  6380. }
  6381.  
  6382.  
  6383. proc Tree::create { path args } {
  6384. Widget::initArgs Tree $args maps
  6385.  
  6386. eval [list frame $path -class Tree] $maps(:cmd)
  6387.  
  6388. if {[info tclversion] > 8.3} { $path configure -padx 0 -pady 0 }
  6389.  
  6390. Widget::initFromODB Tree $path $maps(Tree)
  6391.  
  6392. set ::Tree::sentinal($path.c) 0
  6393.  
  6394. Widget::getVariable $path data
  6395.  
  6396. set data(root)         [list [list]]
  6397. set data(selnodes)     [list]
  6398. set data(upd,level)    0
  6399. set data(upd,nodes)    [list]
  6400. set data(upd,afterid)  ""
  6401. set data(dnd,scroll)   ""
  6402. set data(dnd,afterid)  ""
  6403. set data(dnd,selnodes) [list]
  6404. set data(dnd,node)     ""
  6405.  
  6406. Widget::getVariable $path items
  6407.  
  6408. eval [list canvas $path.c] $maps(.c) -xscrollincrement 8
  6409. bindtags $path.c [list TreeSentinalStart TreeFocus $path.c Canvas  TreeCanvas [winfo toplevel $path] all TreeSentinalEnd]
  6410. pack $path.c -expand yes -fill both
  6411. $path.c bind cross <ButtonPress-1> [list Tree::_cross_event $path]
  6412.  
  6413. bind $path.c <KeyPress-Up>    [list Tree::_keynav up $path]
  6414. bind $path.c <KeyPress-Down>  [list Tree::_keynav down $path]
  6415. bind $path.c <KeyPress-Right> [list Tree::_keynav right $path]
  6416. bind $path.c <KeyPress-Left>  [list Tree::_keynav left $path]
  6417. bind $path.c <KeyPress-space> [list +Tree::_keynav space $path]
  6418.  
  6419. bind $path.c <Control-KeyPress-Up>    [list $path.c yview scroll -1 units]
  6420. bind $path.c <Control-KeyPress-Down>  [list $path.c yview scroll  1 units]
  6421. bind $path.c <Control-KeyPress-Left>  [list $path.c xview scroll -1 units]
  6422. bind $path.c <Control-KeyPress-Right> [list $path.c xview scroll  1 units]
  6423.  
  6424. DragSite::setdrag $path $path.c Tree::_init_drag_cmd  [Widget::cget $path -dragendcmd] 1
  6425. DropSite::setdrop $path $path.c Tree::_over_cmd Tree::_drop_cmd 1
  6426.  
  6427. Widget::create Tree $path
  6428.  
  6429. set w [Widget::cget $path -width]
  6430. set h [Widget::cget $path -height]
  6431. set dy [Widget::cget $path -deltay]
  6432. $path.c configure -width [expr {$w*8}] -height [expr {$h*$dy}]
  6433.  
  6434.  
  6435. set selectcmd Tree::_mouse_select
  6436. Tree::bindText  $path <Button-1>         [list $selectcmd $path set]
  6437. Tree::bindImage $path <Button-1>         [list $selectcmd $path set]
  6438. Tree::bindText  $path <Control-Button-1> [list $selectcmd $path toggle]
  6439. Tree::bindImage $path <Control-Button-1> [list $selectcmd $path toggle]
  6440.  
  6441. $path.c bind TreeItemSentinal <Double-Button-1>  [list set ::Tree::sentinal($path.c) 1]
  6442.  
  6443. return $path
  6444. }
  6445.  
  6446.  
  6447. proc Tree::configure { path args } {
  6448. Widget::getVariable $path data
  6449.  
  6450. set res [Widget::configure $path $args]
  6451.  
  6452. set ch1 [expr {[Widget::hasChanged $path -deltax val]
  6453. || [Widget::hasChanged $path -deltay dy]
  6454. || [Widget::hasChanged $path -padx val]
  6455. || [Widget::hasChanged $path -showlines val]
  6456. || [Widget::hasChanged $path -font font]}]
  6457.  
  6458. set ch2 [expr {[Widget::hasChanged $path -selectbackground val] |
  6459. [Widget::hasChanged $path -selectforeground val]}]
  6460.  
  6461. if {[Widget::hasChanged $path -linesfill fill]
  6462. || [Widget::hasChanged $path -linestipple stipple] } {
  6463. $path.c itemconfigure line  -fill $fill -stipple $stipple
  6464. }
  6465.  
  6466. if {[Widget::hasChanged $path -crossfill fill]} {
  6467. $path.c itemconfigure cross -foreground $fill
  6468. }
  6469.  
  6470. if {[Widget::hasChanged $path -selectfill fill]} {
  6471. if {$fill} {
  6472. foreach event [$path.c bind "node"] {
  6473. $path.c bind "box" $event [$path.c bind "node" $event]
  6474. }
  6475. } else {
  6476. foreach event [$path.c bind "node"] {
  6477. $path.c bind "box" $event {}
  6478. }
  6479. }
  6480. }
  6481.  
  6482. if { $ch1 } {
  6483. _redraw_idle $path 3
  6484. } elseif { $ch2 } {
  6485. _redraw_idle $path 1
  6486. }
  6487.  
  6488. if { [Widget::hasChanged $path -height h] } {
  6489. $path.c configure -height [expr {$h*$dy}]
  6490. }
  6491. if { [Widget::hasChanged $path -width w] } {
  6492. $path.c configure -width [expr {$w*8}]
  6493. }
  6494.  
  6495. if { [Widget::hasChanged $path -redraw bool] && $bool } {
  6496. set upd $data(upd,level)
  6497. set data(upd,level) 0
  6498. _redraw_idle $path $upd
  6499. }
  6500.  
  6501. set force [Widget::hasChanged $path -dragendcmd dragend]
  6502. DragSite::setdrag $path $path.c Tree::_init_drag_cmd $dragend $force
  6503. DropSite::setdrop $path $path.c Tree::_over_cmd Tree::_drop_cmd
  6504.  
  6505. return $res
  6506. }
  6507.  
  6508.  
  6509. proc Tree::cget { path option } {
  6510. return [Widget::cget $path $option]
  6511. }
  6512.  
  6513.  
  6514. proc Tree::insert { path index parent node args } {
  6515. Widget::getVariable $path data
  6516.  
  6517. set node [_node_name $path $node]
  6518. set node [Widget::nextIndex $path $node]
  6519.  
  6520. if {[info exists data($node)]} {
  6521. return -code error "node \"$node\" already exists"
  6522. }
  6523.  
  6524. if {![info exists data($parent)]} {
  6525. return -code error "node \"$parent\" does not exist"
  6526. }
  6527.  
  6528. Widget::init Tree::Node $path.$node $args
  6529.  
  6530. if {[string equal $index "end"]} {
  6531. lappend data($parent) $node
  6532. } else {
  6533. set data($parent) [linsert $data($parent) [incr index] $node]
  6534. }
  6535. set data($node) [list $parent]
  6536.  
  6537. if {[string equal $parent "root"]} {
  6538. _redraw_idle $path 3
  6539. } elseif {[Tree::visible $path $parent]} {
  6540. if {[Widget::getoption $path.$parent -open]} {
  6541. _redraw_idle $path 3
  6542. } else {
  6543. lappend data(upd,nodes) $parent 8
  6544. _redraw_idle $path 2
  6545. }
  6546. }
  6547.  
  6548. return $node
  6549. }
  6550.  
  6551.  
  6552. proc Tree::itemconfigure { path node args } {
  6553. Widget::getVariable $path data
  6554.  
  6555. set node [_node_name $path $node]
  6556. if {[string equal $node "root"] || ![info exists data($node)]} {
  6557. return -code error "node \"$node\" does not exist"
  6558. }
  6559.  
  6560. set result [Widget::configure $path.$node $args]
  6561.  
  6562. _set_help $path $node
  6563.  
  6564. if { [visible $path $node] } {
  6565. set lopt   {}
  6566. set flag   0
  6567. foreach opt {-window -image -drawcross -font -text -fill} {
  6568. set flag [expr {$flag << 1}]
  6569. if {[Widget::hasChanged $path.$node $opt val]} {
  6570. set flag [expr {$flag | 1}]
  6571. }
  6572. }
  6573.  
  6574. if {[Widget::hasChanged $path.$node -open val]} {
  6575. if {[llength $data($node)] > 1} {
  6576. _redraw_idle $path 3
  6577. } else {
  6578. set flag [expr {$flag | 8}]
  6579. }
  6580. }
  6581.  
  6582. if {$data(upd,level) < 3 && [Widget::hasChanged $path.$node -padx x]} {
  6583. _redraw_idle $path 3
  6584. }
  6585.  
  6586. if { $data(upd,level) < 3 && $flag } {
  6587. if { [set idx [lsearch -exact $data(upd,nodes) $node]] == -1 } {
  6588. lappend data(upd,nodes) $node $flag
  6589. } else {
  6590. incr idx
  6591. set flag [expr {[lindex $data(upd,nodes) $idx] | $flag}]
  6592. set data(upd,nodes) [lreplace $data(upd,nodes) $idx $idx $flag]
  6593. }
  6594. _redraw_idle $path 2
  6595. }
  6596. }
  6597. return $result
  6598. }
  6599.  
  6600.  
  6601. proc Tree::itemcget { path node option } {
  6602. Widget::getVariable $path data
  6603. set node [_node_name $path $node]
  6604. if {[string equal $node "root"] || ![info exists data($node)]} {
  6605. return -code error "node \"$node\" does not exist"
  6606. }
  6607.  
  6608. return [Widget::cget $path.$node $option]
  6609. }
  6610.  
  6611.  
  6612. proc Tree::bindText { path event script } {
  6613. if {[string length $script]} {
  6614. append script " \[Tree::_get_node_name [list $path] current 2\]"
  6615. }
  6616. $path.c bind "node" $event $script
  6617. if {[Widget::getoption $path -selectfill]} {
  6618. $path.c bind "box" $event $script
  6619. } else {
  6620. $path.c bind "box" $event {}
  6621. }
  6622. }
  6623.  
  6624.  
  6625. proc Tree::bindImage { path event script } {
  6626. if {[string length $script]} {
  6627. append script " \[Tree::_get_node_name [list $path] current 2\]"
  6628. }
  6629. $path.c bind "img" $event $script
  6630. if {[Widget::getoption $path -selectfill]} {
  6631. $path.c bind "box" $event $script
  6632. } else {
  6633. $path.c bind "box" $event {}
  6634. }
  6635. }
  6636.  
  6637.  
  6638. proc Tree::bindTree { path args } {
  6639. return [eval [list bind $path.c] $args]
  6640. }
  6641.  
  6642.  
  6643. proc Tree::delete { path args } {
  6644. Widget::getVariable $path data
  6645.  
  6646. foreach lnodes $args {
  6647. foreach node $lnodes {
  6648. set node [_node_name $path $node]
  6649. if { ![string equal $node "root"] && [info exists data($node)] } {
  6650. set parent [lindex $data($node) 0]
  6651. set idx       [lsearch -exact $data($parent) $node]
  6652. set data($parent) [lreplace $data($parent) $idx $idx]
  6653. _subdelete $path [list $node]
  6654. }
  6655. }
  6656. }
  6657.  
  6658. _redraw_idle $path 3
  6659. }
  6660.  
  6661.  
  6662. proc Tree::move { path parent node index } {
  6663. Widget::getVariable $path data
  6664.  
  6665. set node [_node_name $path $node]
  6666. if { [string equal $node "root"] || ![info exists data($node)] } {
  6667. return -code error "node \"$node\" does not exist"
  6668. }
  6669. if { ![info exists data($parent)] } {
  6670. return -code error "node \"$parent\" does not exist"
  6671. }
  6672. set p $parent
  6673. while {![string equal $p "root"]} {
  6674. if {[string equal $p $node]} {
  6675. return -code error "node \"$parent\" is a descendant of \"$node\""
  6676. }
  6677. set p [Tree::parent $path $p]
  6678. }
  6679.  
  6680. set oldp        [lindex $data($node) 0]
  6681. set idx         [lsearch -exact $data($oldp) $node]
  6682. set data($oldp) [lreplace $data($oldp) $idx $idx]
  6683. set data($node) [concat [list $parent] [lrange $data($node) 1 end]]
  6684.  
  6685. if {[string equal $index "end"]} {
  6686. lappend data($parent) $node
  6687. } else {
  6688. set data($parent) [linsert $data($parent) [incr index] $node]
  6689. }
  6690.  
  6691. if {([string equal $oldp "root"] ||
  6692. ([visible $path $oldp] && [Widget::getoption $path.$oldp -open]))
  6693. || ([string equal $parent "root"] ||
  6694. ([visible $path $parent]
  6695. && [Widget::getoption $path.$parent -open]))} {
  6696. _redraw_idle $path 3
  6697. }
  6698. }
  6699.  
  6700.  
  6701. proc Tree::reorder { path node neworder } {
  6702. Widget::getVariable $path data
  6703.  
  6704. set node [_node_name $path $node]
  6705. if { ![info exists data($node)] } {
  6706. return -code error "node \"$node\" does not exist"
  6707. }
  6708. set children [lrange $data($node) 1 end]
  6709. if { [llength $children] } {
  6710. set children [BWidget::lreorder $children $neworder]
  6711. set data($node) [linsert $children 0 [lindex $data($node) 0]]
  6712. if { [visible $path $node] && [Widget::getoption $path.$node -open] } {
  6713. _redraw_idle $path 3
  6714. }
  6715. }
  6716. }
  6717.  
  6718.  
  6719. proc Tree::selection { path cmd args } {
  6720. Widget::getVariable $path data
  6721.  
  6722. switch -- $cmd {
  6723. toggle {
  6724. foreach node $args {
  6725. set node [_node_name $path $node]
  6726. if {![info exists data($node)]} {
  6727. return -code error "$path selection toggle:
  6728. Cannot toggle unknown node \"$node\"."
  6729. }
  6730. }
  6731.  
  6732. foreach node $args {
  6733. set node [_node_name $path $node]
  6734. if {[set idx [lsearch -exact $data(selnodes) $node]] != -1} {
  6735. set data(selnodes) [lreplace $data(selnodes) $idx $idx]
  6736. } else {
  6737. lappend data(selnodes) $node
  6738. }
  6739. }
  6740. }
  6741.  
  6742. set {
  6743. foreach node $args {
  6744. set node [_node_name $path $node]
  6745. if {![info exists data($node)]} {
  6746. return -code error "$path selection set:  Cannot select unknown node \"$node\"."
  6747. }
  6748. }
  6749. set data(selnodes) {}
  6750. foreach node $args {
  6751. set node [_node_name $path $node]
  6752. if { [Widget::getoption $path.$node -selectable] } {
  6753. if { [lsearch -exact $data(selnodes) $node] == -1 } {
  6754. lappend data(selnodes) $node
  6755. }
  6756. }
  6757. }
  6758. _call_selectcmd $path
  6759. }
  6760.  
  6761. add {
  6762. foreach node $args {
  6763. set node [_node_name $path $node]
  6764. if {![info exists data($node)]} {
  6765. return -code error "$path selection add:  Cannot select unknown node \"$node\"."
  6766. }
  6767. }
  6768.  
  6769. foreach node $args {
  6770. set node [_node_name $path $node]
  6771. if {[Widget::getoption $path.$node -selectable]} {
  6772. if {[lsearch -exact $data(selnodes) $node] == -1} {
  6773. lappend data(selnodes) $node
  6774. }
  6775. }
  6776. }
  6777. _call_selectcmd $path
  6778. }
  6779.  
  6780. range {
  6781.  
  6782. if {[llength $args] != 2} {
  6783. return -code error  [BWidget::wrongNumArgsString  "$path selection range node1 node2"]
  6784. }
  6785.  
  6786. foreach {node1 node2} $args break
  6787.  
  6788. set node1 [_node_name $path $node1]
  6789. set node2 [_node_name $path $node2]
  6790. if {![info exists data($node1)]} {
  6791. return -code error "$path selection range:  Cannot start range at unknown node \"$node1\"."
  6792. }
  6793. if {![info exists data($node2)]} {
  6794. return -code error "$path selection range:  Cannot end range at unknown node \"$node2\"."
  6795. }
  6796.  
  6797. set nodes {}
  6798. foreach nodeItem [$path.c find withtag node] {
  6799. set node [Tree::_get_node_name $path $nodeItem 2]
  6800. if { [Widget::getoption $path.$node -selectable] } {
  6801. lappend nodes $node
  6802. }
  6803. }
  6804.  
  6805. if {$node1 == "root"} {
  6806. set node1 [lindex $nodes 0]
  6807. }
  6808.  
  6809. if {$node2 == "root"} {
  6810. set node2 [lindex $nodes 0]
  6811. }
  6812.  
  6813. while {[set index1 [lsearch -exact $nodes $node1]] == -1} {
  6814. set node1 [lindex $data($node1) 0]
  6815. }
  6816.  
  6817. while {[set index2 [lsearch -exact $nodes $node2]] == -1} {
  6818. set node2 [lindex $data($node2) 0]
  6819. }
  6820.  
  6821. if {$index2 < $index1} {
  6822. incr index1 $index2
  6823. set index2 [expr {$index1 - $index2}]
  6824. set index1 [expr {$index1 - $index2}]
  6825. }
  6826.  
  6827. set data(selnodes) [lrange $nodes $index1 $index2]
  6828. _call_selectcmd $path
  6829. }
  6830.  
  6831. remove {
  6832. foreach node $args {
  6833. set node [_node_name $path $node]
  6834. if { [set idx [lsearch -exact $data(selnodes) $node]] != -1 } {
  6835. set data(selnodes) [lreplace $data(selnodes) $idx $idx]
  6836. }
  6837. }
  6838. _call_selectcmd $path
  6839. }
  6840.  
  6841. clear {
  6842. if {[llength $args] != 0} {
  6843. return -code error  [BWidget::wrongNumArgsString "$path selection clear"]
  6844. }
  6845. set data(selnodes) {}
  6846. _call_selectcmd $path
  6847. }
  6848.  
  6849. get {
  6850. if {[llength $args] != 0} {
  6851. return -code error  [BWidget::wrongNumArgsString "$path selection get"]
  6852. }
  6853. return $data(selnodes)
  6854. }
  6855.  
  6856. includes {
  6857. if {[llength $args] != 1} {
  6858. return -code error  [BWidget::wrongNumArgsString  "$path selection includes node"]
  6859. }
  6860. set node [lindex $args 0]
  6861. set node [_node_name $path $node]
  6862. return [expr {[lsearch -exact $data(selnodes) $node] != -1}]
  6863. }
  6864.  
  6865. default {
  6866. return
  6867. }
  6868. }
  6869.  
  6870. _redraw_idle $path 1
  6871. }
  6872.  
  6873.  
  6874. proc Tree::getcanvas { path } {
  6875. return $path.c
  6876. }
  6877.  
  6878.  
  6879. proc Tree::exists { path node } {
  6880. Widget::getVariable $path data
  6881. set node [_node_name $path $node]
  6882. return [info exists data($node)]
  6883. }
  6884.  
  6885.  
  6886. proc Tree::visible { path node } {
  6887. Widget::getVariable $path items
  6888. set node [_node_name $path $node]
  6889. return [info exists items($node)]
  6890. }
  6891.  
  6892.  
  6893. proc Tree::parent { path node } {
  6894. Widget::getVariable $path data
  6895.  
  6896. set node [_node_name $path $node]
  6897. if {![info exists data($node)]} {
  6898. return -code error "node \"$node\" does not exist"
  6899. }
  6900. return [lindex $data($node) 0]
  6901. }
  6902.  
  6903.  
  6904. proc Tree::index { path node } {
  6905. Widget::getVariable $path data
  6906.  
  6907. set node [_node_name $path $node]
  6908. if {[string equal $node "root"] || ![info exists data($node)]} {
  6909. return -code error "node \"$node\" does not exist"
  6910. }
  6911. set parent [lindex $data($node) 0]
  6912. return [expr {[lsearch -exact $data($parent) $node] - 1}]
  6913. }
  6914.  
  6915.  
  6916. proc Tree::find { path findInfo {confine ""} } {
  6917. if {[regexp -- {^@([0-9]+),([0-9]+)$} $findInfo match x y]} {
  6918. set x [$path.c canvasx $x]
  6919. set y [$path.c canvasy $y]
  6920. } elseif {[regexp -- {^[0-9]+$} $findInfo lineNumber]} {
  6921. set dy [Widget::cget $path -deltay]
  6922. set y  [expr {$dy*($lineNumber+0.5)}]
  6923. set confine ""
  6924. } else {
  6925. return -code error "invalid find spec \"$findInfo\""
  6926. }
  6927.  
  6928. set found  0
  6929. set region [$path.c bbox all]
  6930. if {[llength $region]} {
  6931. set xi [lindex $region 0]
  6932. set xs [lindex $region 2]
  6933. foreach id [$path.c find overlapping $xi $y $xs $y] {
  6934. set ltags [$path.c gettags $id]
  6935. set item  [lindex $ltags 1]
  6936. if { [string equal $item "node"] ||
  6937. [string equal $item "img"]  ||
  6938. [string equal $item "win"] } {
  6939. set node  [Tree::_get_node_name $path $id 2]
  6940. set found 1
  6941. break
  6942. }
  6943. }
  6944. }
  6945.  
  6946. if {$found} {
  6947. if {[string equal $confine "confine"]} {
  6948. set padx [_get_node_padx $path $node]
  6949. set xi [expr {[lindex [$path.c coords n:$node] 0] - $padx}]
  6950. set xs [lindex [$path.c bbox n:$node] 2]
  6951. if {$x >= $xi && $x <= $xs} {
  6952. return $node
  6953. }
  6954. } else {
  6955. return $node
  6956. }
  6957. }
  6958.  
  6959. return
  6960. }
  6961.  
  6962.  
  6963. proc Tree::line { path node } {
  6964. Widget::getVariable $path items
  6965. set node [_node_name $path $node]
  6966. set line [lindex $items($node) 0]
  6967. if {[string length $line]} { return $line }
  6968. return -1
  6969. }
  6970.  
  6971.  
  6972. proc Tree::nodes { path node {first ""} {last ""} } {
  6973. Widget::getVariable $path data
  6974.  
  6975. set node [_node_name $path $node]
  6976. if {![info exists data($node)]} {
  6977. return -code error "node \"$node\" does not exist"
  6978. }
  6979.  
  6980. if {![string length $first]} {
  6981. return [lrange $data($node) 1 end]
  6982. }
  6983.  
  6984. if {![string length $last]} {
  6985. return [lindex [lrange $data($node) 1 end] $first]
  6986. } else {
  6987. return [lrange [lrange $data($node) 1 end] $first $last]
  6988. }
  6989. }
  6990.  
  6991.  
  6992.  
  6993. proc Tree::visiblenodes { path {node root} } {
  6994. Widget::getVariable $path data
  6995.  
  6996. set nodes [list]
  6997. foreach node [lrange $data($node) 1 end] {
  6998. lappend nodes $node
  6999. if {[Widget::getoption $path.$node -open]} {
  7000. eval lappend nodes [Tree::visiblenodes $path $node]
  7001. }
  7002. }
  7003.  
  7004. return $nodes
  7005. }
  7006.  
  7007. proc Tree::see { path node } {
  7008. Widget::getVariable $path data
  7009. Widget::getVariable $path items
  7010.  
  7011. set node [_node_name $path $node]
  7012. if {[Widget::getoption $path -redraw] && $data(upd,afterid) != ""} {
  7013. after cancel $data(upd,afterid)
  7014. _redraw_tree $path
  7015. }
  7016.  
  7017. if {[info exists items($node)]} {
  7018. Tree::_see $path [lindex $items($node) 1]
  7019. }
  7020. }
  7021.  
  7022.  
  7023. proc Tree::opentree { path node {recursive 1} } {
  7024. Widget::getVariable $path data
  7025.  
  7026. set node [_node_name $path $node]
  7027. if {[string equal $node "root"] || ![info exists data($node)]} {
  7028. return -code error "node \"$node\" does not exist"
  7029. }
  7030.  
  7031. _recexpand $path $node 1 $recursive [Widget::getoption $path -opencmd]
  7032. _redraw_idle $path 3
  7033. }
  7034.  
  7035.  
  7036. proc Tree::closetree { path node {recursive 1} } {
  7037. Widget::getVariable $path data
  7038.  
  7039. set node [_node_name $path $node]
  7040. if {[string equal $node "root"] || ![info exists data($node)]} {
  7041. return -code error "node \"$node\" does not exist"
  7042. }
  7043.  
  7044. _recexpand $path $node 0 $recursive [Widget::getoption $path -closecmd]
  7045. _redraw_idle $path 3
  7046. }
  7047.  
  7048.  
  7049. proc Tree::toggle { path node } {
  7050. if {[Tree::itemcget $path $node -open]} {
  7051. $path closetree $node 0
  7052. } else {
  7053. $path opentree $node 0
  7054. }
  7055. }
  7056.  
  7057.  
  7058. proc Tree::edit { path node text {verifycmd ""} {clickres 0} {select 1} } {
  7059. variable _edit
  7060. Widget::getVariable $path data
  7061. Widget::getVariable $path items
  7062.  
  7063. set node [_node_name $path $node]
  7064. if {[Widget::getoption $path -redraw] && $data(upd,afterid) != ""} {
  7065. after cancel $data(upd,afterid)
  7066. _redraw_tree $path
  7067. }
  7068.  
  7069. if {[info exists items($node)]} {
  7070. set _edit(editing) 1
  7071.  
  7072. set idn [lindex $items($node) 1]
  7073.  
  7074. Tree::_see $path $idn
  7075.  
  7076. set oldfg  [$path.c itemcget $idn -fill]
  7077. set sbg    [Widget::cget $path -selectbackground]
  7078. set coords [$path.c coords $idn]
  7079. set x      [lindex $coords 0]
  7080. set y      [lindex $coords 1]
  7081. set ht     [$path.c cget -highlightthickness]
  7082. set bd     [expr {[$path.c cget -borderwidth] + $ht}]
  7083. set w      [expr {[winfo width $path] - 2 * $bd}]
  7084. set wmax   [expr {[$path.c canvasx $w] - $x}]
  7085.  
  7086. set _edit(wait) 0
  7087. set _edit(path) $path
  7088. set _edit(node) $node
  7089. set _edit(text) $text
  7090.  
  7091. $path.c itemconfigure $idn    -fill [Widget::cget $path -background]
  7092. $path.c itemconfigure s:$node -fill {} -outline {}
  7093.  
  7094. set frame  [frame $path.edit  -relief flat -borderwidth 0 -highlightthickness 0  -background [Widget::cget $path -background]]
  7095. set ent    [entry $frame.edit  -width              0      -relief             solid  -borderwidth        1      -highlightthickness 0      -foreground         [Widget::getoption $path.$node -fill]  -background         [Widget::cget $path -background]  -selectforeground   [Widget::cget $path -selectforeground]  -selectbackground   $sbg   -font               [_get_option $path $node -font]  -textvariable       Tree::_edit(text)]
  7096. pack $ent -ipadx 8 -anchor w
  7097.  
  7098. set _edit(frame) $frame
  7099. set _edit(entry) $ent
  7100.  
  7101. set idw [$path.c create window $x $y -window $frame -anchor w]
  7102. trace variable Tree::_edit(text) w  [list Tree::_update_edit_size $path $ent $idw $wmax]
  7103. tkwait visibility $ent
  7104. grab $frame
  7105. BWidget::focus set $ent
  7106.  
  7107. _update_edit_size $path $ent $idw $wmax
  7108. update
  7109.  
  7110. if {$select} {
  7111. $ent selection range 0 end
  7112. $ent icursor end
  7113. $ent xview end
  7114. }
  7115.  
  7116. bindtags $ent [list $ent Entry]
  7117. bind $ent <Escape> {set Tree::_edit(wait) 0}
  7118. bind $ent <Return> {set Tree::_edit(wait) 1}
  7119. if {$clickres == 0 || $clickres == 1} {
  7120. bind $frame <Button>  [list set Tree::_edit(wait) $clickres]
  7121. }
  7122.  
  7123. set ok 0
  7124. while {!$ok} {
  7125. focus -force $ent
  7126. tkwait variable Tree::_edit(wait)
  7127. if {!$_edit(wait) || ![llength $verifycmd] ||
  7128. [uplevel \#0 $verifycmd [list $_edit(text)]]} {
  7129. set ok 1
  7130. }
  7131. }
  7132.  
  7133. trace vdelete Tree::_edit(text) w  [list Tree::_update_edit_size $path $ent $idw $wmax]
  7134. grab release $frame
  7135. BWidget::focus release $ent
  7136.  
  7137. set _edit(editing) 0
  7138.  
  7139. destroy $frame
  7140. $path.c delete $idw
  7141. $path.c itemconfigure $idn    -fill $oldfg
  7142. $path.c itemconfigure s:$node -fill $sbg -outline $sbg
  7143.  
  7144. if {$_edit(wait)} {
  7145. return $_edit(text)
  7146. }
  7147. }
  7148. }
  7149.  
  7150.  
  7151. proc Tree::editing { path } {
  7152. variable _edit
  7153. if {$_edit(editing) && $_edit(path) eq $path} { return 1 }
  7154. return 0
  7155. }
  7156.  
  7157.  
  7158. proc Tree::xview { path args } {
  7159. return [eval [linsert $args 0 $path.c xview]]
  7160. }
  7161.  
  7162.  
  7163. proc Tree::yview { path args } {
  7164. return [eval [linsert $args 0 $path.c yview]]
  7165. }
  7166.  
  7167.  
  7168. proc Tree::search { path args } {
  7169. Widget::getVariable $path data
  7170.  
  7171. array set _args {
  7172. -pattern  *
  7173. }
  7174. array set _args $args
  7175.  
  7176. return [array names data $_args(-pattern)]
  7177. }
  7178.  
  7179.  
  7180. proc Tree::level { path node } {
  7181. Widget::getVariable $path data
  7182.  
  7183. if {[string equal $node "root"]} { return 0 }
  7184.  
  7185. if {![info exists data($node)]} {
  7186. return -code error "node \"$node\" does not exists"
  7187. }
  7188.  
  7189. set level  1
  7190. set parent [lindex $data($node) 0]
  7191. while {![string equal $parent "root"]} {
  7192. incr level
  7193. set parent [lindex $data($parent) 0]
  7194. }
  7195.  
  7196. return $level
  7197. }
  7198.  
  7199.  
  7200. proc Tree::_call_selectcmd { path } {
  7201. Widget::getVariable $path data
  7202.  
  7203. set selectcmd [Widget::getoption $path -selectcommand]
  7204. if {[llength $selectcmd]} {
  7205. lappend selectcmd $path
  7206. lappend selectcmd $data(selnodes)
  7207. uplevel \#0 $selectcmd
  7208. }
  7209. return
  7210. }
  7211.  
  7212.  
  7213. proc Tree::_update_edit_size { path entry idw wmax args } {
  7214. set entw [winfo reqwidth $entry]
  7215. if {$entw + 8 >= $wmax} {
  7216. $path.c itemconfigure $idw -width $wmax
  7217. } else {
  7218. $path.c itemconfigure $idw -width 0
  7219. }
  7220. }
  7221.  
  7222.  
  7223. proc Tree::_see { path idn } {
  7224. set bbox [$path.c bbox $idn]
  7225. set scrl [$path.c cget -scrollregion]
  7226.  
  7227. set ymax [lindex $scrl 3]
  7228. set dy   [$path.c cget -yscrollincrement]
  7229. set yv   [$path yview]
  7230. set yv0  [expr {round([lindex $yv 0]*$ymax/$dy)}]
  7231. set yv1  [expr {round([lindex $yv 1]*$ymax/$dy)}]
  7232. set y    [expr {int([lindex [$path.c coords $idn] 1]/$dy)}]
  7233.  
  7234. if {$y < $yv0} {
  7235. $path.c yview scroll [expr {$y-$yv0}] units
  7236. } elseif { $y >= $yv1 } {
  7237. $path.c yview scroll [expr {$y-$yv1+1}] units
  7238. }
  7239.  
  7240. set xmax [lindex $scrl 2]
  7241. set dx   [$path.c cget -xscrollincrement]
  7242. set xv   [$path xview]
  7243. set x0   [expr {int([lindex $bbox 0]/$dx)}]
  7244. set xv0  [expr {round([lindex $xv 0]*$xmax/$dx)}]
  7245. set xv1  [expr {round([lindex $xv 1]*$xmax/$dx)}]
  7246.  
  7247. if {$x0 >= $xv1 || $x0 < $xv0} {
  7248. $path.c xview scroll [expr {$x0-$xv0}] units
  7249. }
  7250. }
  7251.  
  7252.  
  7253. proc Tree::_recexpand { path node expand recursive cmd } {
  7254. Widget::getVariable $path data
  7255.  
  7256. if {[Widget::getoption $path.$node -open] != $expand} {
  7257. Widget::setoption $path.$node -open $expand
  7258. if {[llength $cmd]} {
  7259. uplevel \#0 $cmd [list $node]
  7260. }
  7261. }
  7262.  
  7263. if {$recursive} {
  7264. foreach subnode [lrange $data($node) 1 end] {
  7265. _recexpand $path $subnode $expand $recursive $cmd
  7266. }
  7267. }
  7268. }
  7269.  
  7270.  
  7271. proc Tree::_subdelete { path lnodes } {
  7272. Widget::getVariable $path data
  7273.  
  7274. set sel $data(selnodes)
  7275.  
  7276. while {[llength $lnodes]} {
  7277. set lsubnodes [list]
  7278. foreach node $lnodes {
  7279. foreach subnode [lrange $data($node) 1 end] {
  7280. lappend lsubnodes $subnode
  7281. }
  7282. unset data($node)
  7283. set idx [lsearch -exact $sel $node]
  7284. if {$idx >= 0} {
  7285. set sel [lreplace $sel $idx $idx]
  7286. }
  7287. if {[set win [Widget::getoption $path.$node -window]] != ""} {
  7288. destroy $win
  7289. }
  7290. Widget::destroy $path.$node 0
  7291. }
  7292. set lnodes $lsubnodes
  7293. }
  7294.  
  7295. set data(selnodes) $sel
  7296. }
  7297.  
  7298.  
  7299. proc Tree::_update_scrollregion { path } {
  7300. set bd   [$path.c cget -borderwidth]
  7301. set ht   [$path.c cget -highlightthickness]
  7302. set bd   [expr {2 * ($bd + $ht)}]
  7303. set w    [expr {[winfo width  $path] - $bd}]
  7304. set h    [expr {[winfo height $path] - $bd}]
  7305. set xinc [$path.c cget -xscrollincrement]
  7306. set yinc [$path.c cget -yscrollincrement]
  7307. set bbox [$path.c bbox node]
  7308. if {[llength $bbox]} {
  7309. set xs [lindex $bbox 2]
  7310. set ys [lindex $bbox 3]
  7311.  
  7312. if {$w < $xs} {
  7313. set w [expr {int($xs)}]
  7314. if {[set r [expr {$w % $xinc}]]} {
  7315. set w [expr {$w+$xinc-$r}]
  7316. }
  7317. }
  7318. if {$h < $ys} {
  7319. set h [expr {int($ys)}]
  7320. if {[set r [expr {$h % $yinc}]]} {
  7321. set h [expr {$h+$yinc-$r}]
  7322. }
  7323. }
  7324. }
  7325.  
  7326. $path.c configure -scrollregion [list 0 0 $w $h]
  7327.  
  7328. if {[Widget::getoption $path -selectfill]} {
  7329. _redraw_selection $path
  7330. }
  7331. }
  7332.  
  7333.  
  7334. proc Tree::_cross_event { path } {
  7335. Widget::getVariable $path data
  7336.  
  7337. set node [Tree::_get_node_name $path current 1]
  7338. if {[Widget::getoption $path.$node -open]} {
  7339. Tree::itemconfigure $path $node -open 0
  7340. if {[llength [set cmd [Widget::getoption $path -closecmd]]]} {
  7341. uplevel \#0 $cmd [list $node]
  7342. }
  7343. } else {
  7344. Tree::itemconfigure $path $node -open 1
  7345. if {[llength [set cmd [Widget::getoption $path -opencmd]]]} {
  7346. uplevel \#0 $cmd [list $node]
  7347. }
  7348. }
  7349. }
  7350.  
  7351.  
  7352. proc Tree::_draw_cross { path node open x y } {
  7353. Widget::getVariable $path items
  7354. set idc [lindex $items($node) 2]
  7355.  
  7356. if {$open} {
  7357. set img [Widget::cget $path -crossopenimage]
  7358. set bmp [Widget::cget $path -crossopenbitmap]
  7359. } else {
  7360. set img [Widget::cget $path -crosscloseimage]
  7361. set bmp [Widget::cget $path -crossclosebitmap]
  7362. }
  7363.  
  7364. if {[string length $idc]} {
  7365. if {![string length $img]} {
  7366. $path.c itemconfigure $idc -bitmap $bmp
  7367. } else {
  7368. $path.c itemconfigure $idc -image $img
  7369. }
  7370. return $idc
  7371. }
  7372.  
  7373. if {![Widget::getoption $path -showlines]} { set x [expr {$x + 6}] }
  7374.  
  7375. if {![string length $img]} {
  7376. set idc [$path.c create bitmap $x $y  -bitmap     $bmp  -background [$path.c cget -background]  -foreground [Widget::getoption $path -crossfill]  -tags       [list cross c:$node] -anchor c]
  7377. } else {
  7378. set idc [$path.c create image $x $y  -image      $img  -tags       [list cross c:$node] -anchor c]
  7379. }
  7380.  
  7381. return $idc
  7382. }
  7383.  
  7384.  
  7385. proc Tree::_draw_node { path node x0 y0 deltax deltay padx showlines } {
  7386. Widget::getVariable $path data
  7387. Widget::getVariable $path items
  7388.  
  7389. set x1 [expr {$x0+$deltax+5}]
  7390. set y1 $y0
  7391. if {$showlines} {
  7392. set i [$path.c create line $x0 $y0 $x1 $y0  -fill    [Widget::getoption $path -linesfill]    -stipple [Widget::getoption $path -linestipple]  -tags    line]
  7393.  
  7394. lappend items($node) $i
  7395. } else {
  7396. lappend items($node) ""
  7397. }
  7398.  
  7399. set i [$path.c create text [expr {$x1+$padx}] $y0  -anchor w  -text   [Widget::getoption $path.$node -text]  -fill   [Widget::getoption $path.$node -fill]  -font   [_get_option $path $node -font]  -tags   [Tree::_get_node_tags $path $node [list node n:$node]]]
  7400. lappend items($node) $i
  7401.  
  7402. set len [expr {[llength $data($node)] > 1}]
  7403. set dc  [Widget::getoption $path.$node -drawcross]
  7404. set exp [Widget::getoption $path.$node -open]
  7405.  
  7406. if {$len && $exp} {
  7407. set y1 [_draw_subnodes $path [lrange $data($node) 1 end]  [expr {$x0+$deltax}] $y0 $deltax $deltay $padx $showlines]
  7408. }
  7409.  
  7410. if {![string equal $dc "never"] && ($len || [string equal $dc "allways"])} {
  7411. lappend items($node) [_draw_cross $path $node $exp $x0 $y0]
  7412. } else {
  7413. lappend items($node) ""
  7414. }
  7415.  
  7416. if {[set win [Widget::getoption $path.$node -window]] != ""} {
  7417. set a [Widget::cget $path.$node -anchor]
  7418. set i [$path.c create window $x1 $y0 -window $win -anchor $a  -tags [Tree::_get_node_tags $path $node [list win i:$node]]]
  7419. lappend items($node) $i
  7420. } elseif {[set img [Widget::getoption $path.$node -image]] != ""} {
  7421. set a [Widget::cget $path.$node -anchor]
  7422. set i [$path.c create image $x1 $y0 -image $img -anchor $a  -tags   [Tree::_get_node_tags $path $node [list img i:$node]]]
  7423. lappend items($node) $i
  7424. } else {
  7425. lappend items($node) ""
  7426. }
  7427.  
  7428. set nid [lindex $items($node) 1]
  7429. set iid [lindex $items($node) 3]
  7430. set box [$path.c bbox $nid $iid]
  7431. set id [$path.c create rect 0 [lindex $box 1]  [winfo screenwidth $path] [lindex $box 3]  -tags [Tree::_get_node_tags $path $node [list box b:$node]]  -fill {} -outline {}]
  7432. $path.c lower $id
  7433. lappend items($node) $id
  7434.  
  7435. _set_help $path $node
  7436.  
  7437. return $y1
  7438. }
  7439.  
  7440.  
  7441. proc Tree::_draw_subnodes { path nodes x0 y0 deltax deltay padx showlines } {
  7442. set y1 $y0
  7443. foreach node $nodes {
  7444. set padx   [_get_node_padx $path $node]
  7445. set deltax [_get_node_deltax $path $node]
  7446. set yp $y1
  7447. set y1 [_draw_node $path $node $x0 [expr {$y1+$deltay}]  $deltax $deltay $padx $showlines]
  7448. }
  7449. if {$showlines && [llength $nodes]} {
  7450. if {$y0 < 0} {
  7451. incr y0 $deltay
  7452. }
  7453. set id [$path.c create line $x0 $y0 $x0 [expr {$yp+$deltay}]  -fill    [Widget::getoption $path -linesfill]    -stipple [Widget::getoption $path -linestipple]  -tags    line]
  7454.  
  7455. $path.c lower $id
  7456. }
  7457. return $y1
  7458. }
  7459.  
  7460.  
  7461. proc Tree::_update_nodes { path } {
  7462. Widget::getVariable $path data
  7463. Widget::getVariable $path items
  7464.  
  7465. foreach {node flag} $data(upd,nodes) {
  7466. if {![info exists items($node)]} { continue }
  7467. set idn [lindex $items($node) 1]
  7468.  
  7469. set padx   [_get_node_padx $path $node]
  7470. set deltax [_get_node_deltax $path $node]
  7471. set c  [$path.c coords $idn]
  7472. set x1 [expr {[lindex $c 0]-$padx}]
  7473. set x0 [expr {$x1-$deltax-5}]
  7474. set y0 [lindex $c 1]
  7475. if {$flag & 48} {
  7476. set win  [Widget::getoption $path.$node -window]
  7477. set img  [Widget::getoption $path.$node -image]
  7478. set anc  [Widget::cget $path.$node -anchor]
  7479. set idi  [lindex $items($node) 3]
  7480. set type [lindex [$path.c gettags $idi] 1]
  7481. if {[string length $win]} {
  7482. if {[string equal $type "win"]} {
  7483. $path.c itemconfigure $idi -window $win
  7484. } else {
  7485. $path.c delete $idi
  7486. set tags [_get_node_tags $path $node [list win i:$node]]
  7487. set idi [$path.c create window $x1 $y0 -window $win  -anchor $anc -tags $tags]
  7488. set items($node) [lreplace $items($node) 3 3 $idi]
  7489. }
  7490. } elseif {[string length $img]} {
  7491. if {[string equal $type "img"]} {
  7492. $path.c itemconfigure $idi -image $img
  7493. } else {
  7494. $path.c delete $idi
  7495. set tags [_get_node_tags $path $node [list win i:$node]]
  7496. set idi [$path.c create image $x1 $y0 -image $img  -anchor $anc -tags $tags]
  7497. set items($node) [lreplace $items($node) 3 3 $idi]
  7498. }
  7499. } else {
  7500. $path.c delete $idi
  7501. set items($node) [lreplace $items($node) 3 3 ""]
  7502. }
  7503. }
  7504.  
  7505. if {$flag & 8} {
  7506. set len [expr {[llength $data($node)] > 1}]
  7507. set dc  [Widget::getoption $path.$node -drawcross]
  7508. set exp [Widget::getoption $path.$node -open]
  7509.  
  7510. if {![string equal $dc "never"]
  7511. && ($len || [string equal $dc "allways"])} {
  7512. set idc [_draw_cross $path $node $exp $x0 $y0]
  7513. set items($node) [lreplace $items($node) 2 2 $idc]
  7514. } else {
  7515. set idc [lindex $items($node) 2]
  7516. $path.c delete $idc
  7517. set items($node) [lreplace $items($node) 2 2 ""]
  7518. }
  7519. }
  7520.  
  7521. if {$flag & 7} {
  7522. $path.c itemconfigure $idn  -text [Widget::getoption $path.$node -text]  -fill [Widget::getoption $path.$node -fill]  -font [_get_option $path $node -font]
  7523. }
  7524. }
  7525. }
  7526.  
  7527.  
  7528. proc Tree::_draw_tree { path } {
  7529. Widget::getVariable $path data
  7530. Widget::getVariable $path items
  7531.  
  7532. if {[info exists items]} { unset items }
  7533.  
  7534. $path.c delete all
  7535. set cursor [$path.c cget -cursor]
  7536. $path.c configure -cursor watch
  7537.  
  7538. set x0 8
  7539. if {![Widget::getoption $path -showlines]} { set x0 0 }
  7540.  
  7541. Tree::_draw_subnodes $path [lrange $data(root) 1 end] $x0  [expr {-[Widget::cget $path -deltay]/2}]  [Widget::getoption $path -deltax]  [Widget::cget $path -deltay]  [Widget::getoption $path -padx]    [Widget::getoption $path -showlines]
  7542. $path.c configure -cursor $cursor
  7543. }
  7544.  
  7545.  
  7546. proc Tree::_redraw_tree { path } {
  7547. Widget::getVariable $path data
  7548.  
  7549. if {[Widget::getoption $path -redraw]} {
  7550. if {$data(upd,level) == 2} {
  7551. _update_nodes $path
  7552. } elseif {$data(upd,level) == 3} {
  7553. _draw_tree $path
  7554. }
  7555. _redraw_selection $path
  7556. _update_scrollregion $path
  7557. set data(upd,nodes)   {}
  7558. set data(upd,level)   0
  7559. set data(upd,afterid) ""
  7560. }
  7561. }
  7562.  
  7563.  
  7564. proc Tree::_redraw_selection { path } {
  7565. Widget::getVariable $path data
  7566.  
  7567. set selbg [Widget::cget $path -selectbackground]
  7568. set selfg [Widget::cget $path -selectforeground]
  7569. set fill  [Widget::getoption $path -selectfill]
  7570. if {$fill} {
  7571. set scroll [$path.c cget -scrollregion]
  7572. if {[llength $scroll]} {
  7573. set xmax [expr {[lindex $scroll 2]-1}]
  7574. } else {
  7575. set xmax [winfo width $path]
  7576. }
  7577. }
  7578. foreach id [$path.c find withtag sel] {
  7579. set node [Tree::_get_node_name $path $id 1]
  7580. $path.c itemconfigure "n:$node"  -fill [Widget::getoption $path.$node -fill]
  7581. }
  7582. $path.c delete sel
  7583. foreach node $data(selnodes) {
  7584. set bbox [$path.c bbox "n:$node"]
  7585. if {[llength $bbox]} {
  7586. if {$fill} {
  7587. set bbox [$path.c bbox "n:$node" "i:$node"]
  7588. set bbox [list 0 [lindex $bbox 1] $xmax [lindex $bbox 3]]
  7589. }
  7590. set id [$path.c create rectangle $bbox -tags [list sel s:$node]  -fill $selbg -outline $selbg]
  7591. $path.c itemconfigure "n:$node" -fill $selfg
  7592. $path.c lower $id
  7593. }
  7594. }
  7595. }
  7596.  
  7597.  
  7598. proc Tree::_redraw_idle { path level } {
  7599. Widget::getVariable $path data
  7600.  
  7601. if {[Widget::getoption $path -redraw] && $data(upd,afterid) == ""} {
  7602. set data(upd,afterid) [after idle [list Tree::_redraw_tree $path]]
  7603. }
  7604. if {$level > $data(upd,level)} {
  7605. set data(upd,level) $level
  7606. }
  7607. return ""
  7608. }
  7609.  
  7610.  
  7611. proc Tree::_init_drag_cmd { path X Y top } {
  7612. set path [winfo parent $path]
  7613. set ltags [$path.c gettags current]
  7614. set item  [lindex $ltags 1]
  7615. if {[string equal $item "node"]
  7616. || [string equal $item "img"]
  7617. || [string equal $item "win"]} {
  7618. set node [Tree::_get_node_name $path current 2]
  7619. if {[llength [set cmd [Widget::getoption $path -draginitcmd]]]} {
  7620. return [uplevel \#0 $cmd [list $path $node $top]]
  7621. }
  7622. if {[set type [Widget::getoption $path -dragtype]] == ""} {
  7623. set type "TREE_NODE"
  7624. }
  7625. if {[set img [Widget::getoption $path.$node -image]] != ""} {
  7626. pack [label $top.l -image $img -padx 0 -pady 0]
  7627. }
  7628. return [list $type {copy move link} $node]
  7629. }
  7630. return {}
  7631. }
  7632.  
  7633.  
  7634. proc Tree::_drop_cmd { path source X Y op type dnddata } {
  7635. set path [winfo parent $path]
  7636. Widget::getVariable $path data
  7637.  
  7638. $path.c delete drop
  7639. if {[string length $data(dnd,afterid)]} {
  7640. after cancel $data(dnd,afterid)
  7641. set data(dnd,afterid) ""
  7642. }
  7643. set data(dnd,scroll) ""
  7644. if {[llength $data(dnd,node)]
  7645. && [llength [set cmd [Widget::getoption $path -dropcmd]]]} {
  7646. return [uplevel \#0 $cmd  [list $path $source $data(dnd,node) $op $type $dnddata]]
  7647. }
  7648. return 0
  7649. }
  7650.  
  7651.  
  7652. proc Tree::_over_cmd { path source event X Y op type dnddata } {
  7653. set path [winfo parent $path]
  7654. Widget::getVariable $path data
  7655.  
  7656. if {[string equal $event "leave"]} {
  7657. $path.c delete drop
  7658. if {[string length $data(dnd,afterid)]} {
  7659. after cancel $data(dnd,afterid)
  7660. set data(dnd,afterid) ""
  7661. }
  7662. set data(dnd,scroll) ""
  7663. return 0
  7664. }
  7665.  
  7666. if {[string equal $event "enter"]} {
  7667. set mode [Widget::getoption $path -dropovermode]
  7668. set data(dnd,mode) 0
  7669. foreach c {w p n} {
  7670. set data(dnd,mode) [expr {($data(dnd,mode) << 1)
  7671. | ([string first $c $mode] != -1)}]
  7672. }
  7673. set bbox [$path.c bbox all]
  7674. if {[llength $bbox]} {
  7675. set data(dnd,xs) [lindex $bbox 2]
  7676. set data(dnd,empty) 0
  7677. } else {
  7678. set data(dnd,xs) 0
  7679. set data(dnd,empty) 1
  7680. }
  7681. set data(dnd,node) {}
  7682. }
  7683.  
  7684. set x [expr {$X-[winfo rootx $path]}]
  7685. set y [expr {$Y-[winfo rooty $path]}]
  7686.  
  7687. $path.c delete drop
  7688. set data(dnd,node) {}
  7689.  
  7690. if {$data(dnd,mode) != 4 && [_auto_scroll $path $x $y] != ""} { return 2 }
  7691.  
  7692. if {$data(dnd,mode) & 4} {
  7693. set target [list widget]
  7694. set vmode  4
  7695. } else {
  7696. set target [list ""]
  7697. set vmode  0
  7698. }
  7699.  
  7700. if {($data(dnd,mode) & 2) && $data(dnd,empty)} {
  7701. lappend target [list root 0]
  7702. set vmode  [expr {$vmode | 2}]
  7703. }
  7704.  
  7705. set xs $data(dnd,xs)
  7706. set xc [$path.c canvasx $x]
  7707. if {$xc <= $xs} {
  7708. set yc   [$path.c canvasy $y]
  7709. set dy   [$path.c cget -yscrollincrement]
  7710. set line [expr {int($yc/$dy)}]
  7711. set xi   0
  7712. set yi   [expr {$line*$dy}]
  7713. set ys   [expr {$yi+$dy}]
  7714. set found 0
  7715. foreach id [$path.c find overlapping $xi $yi $xs $ys] {
  7716. set ltags [$path.c gettags $id]
  7717. set item  [lindex $ltags 1]
  7718. if {[string equal $item "node"]
  7719. || [string equal $item "img"]
  7720. || [string equal $item "win"]} {
  7721. set node [Tree::_get_node_name $path $id 2]
  7722. set found 1
  7723. break
  7724. }
  7725. }
  7726.  
  7727. if {$found} {
  7728. set padx   [_get_node_padx $path $node]
  7729. set deltax [_get_node_deltax $path $node]
  7730. set xi [expr {[lindex [$path.c coords n:$node] 0] - $padx - 1}]
  7731. if {$data(dnd,mode) & 1} {
  7732. lappend target $node
  7733. set vmode [expr {$vmode | 1}]
  7734. } else {
  7735. lappend target ""
  7736. }
  7737.  
  7738. if {$data(dnd,mode) & 2} {
  7739. if {$yc >= $yi+$dy/2} {
  7740. if {[Widget::getoption $path.$node -open] &&
  7741. [llength $data($node)] > 1} {
  7742. set parent $node
  7743. set index  0
  7744. set xli    [expr {$xi-5}]
  7745. } elseif {[Widget::getoption $path.$node -open]} {
  7746. set parent $node
  7747. set index  0
  7748. set xli    [expr {$xi-5}]
  7749. } else {
  7750. set parent [lindex $data($node) 0]
  7751. set index  [lsearch -exact $data($parent) $node]
  7752. set xli    [expr {$xi - $deltax - 5}]
  7753. }
  7754. set yl $ys
  7755. } else {
  7756. set parent [lindex $data($node) 0]
  7757. set index  [expr {[lsearch -exact $data($parent) $node] - 1}]
  7758. set xli    [expr {$xi - $deltax - 5}]
  7759. set yl     $yi
  7760. }
  7761. lappend target [list $parent $index]
  7762. set vmode  [expr {$vmode | 2}]
  7763. } else {
  7764. lappend target {}
  7765. }
  7766.  
  7767. if {($vmode & 3) == 3} {
  7768. if {$yc-$yi <= 3 || $ys-$yc <= 3} {
  7769. lappend target "position"
  7770. } else {
  7771. lappend target "node"
  7772. }
  7773. }
  7774. }
  7775. }
  7776.  
  7777. if {$vmode && [llength [set cmd [Widget::getoption $path -dropovercmd]]]} {
  7778. set res     [uplevel \#0 $cmd  [list $path $source $target $op $type $dnddata]]
  7779. set code    [lindex $res 0]
  7780. set newmode 0
  7781. if {$code & 1} {
  7782. set mode [lindex $res 1]
  7783. if {($vmode & 1) && [string equal $mode "node"]} {
  7784. set newmode 1
  7785. } elseif {($vmode & 2) && [string equal $mode "position"]} {
  7786. set newmode 2
  7787. } elseif {($vmode & 4) && [string equal $mode "widget"]} {
  7788. set newmode 4
  7789. }
  7790. }
  7791. set vmode $newmode
  7792. } else {
  7793. if {($vmode & 3) == 3} {
  7794. if {[string equal [lindex $target 3] "position"]} {
  7795. set vmode [expr {$vmode & ~1}]
  7796. } else {
  7797. set vmode [expr {$vmode & ~2}]
  7798. }
  7799. }
  7800.  
  7801. if {$data(dnd,mode) == 4 || $data(dnd,mode) == 0} {
  7802. set code 1
  7803. } else {
  7804. set code 3
  7805. }
  7806. }
  7807.  
  7808. if {!$data(dnd,empty)} {
  7809. if {$vmode & 1} {
  7810. set data(dnd,node) [list "node" [lindex $target 1]]
  7811. $path.c create rectangle $xi $yi $xs $ys -tags drop
  7812. } elseif {$vmode & 2} {
  7813. set data(dnd,node) [concat "position" [lindex $target 2]]
  7814. $path.c create line  [list $xli [expr {$yl-$dy/2}] $xli $yl $xs $yl] -tags drop
  7815. } elseif {$vmode & 4} {
  7816. set data(dnd,node) [list "widget"]
  7817. } else {
  7818. set code [expr {$code & 2}]
  7819. }
  7820. }
  7821.  
  7822. if {$code & 1} {
  7823. DropSite::setcursor based_arrow_down
  7824. } else {
  7825. DropSite::setcursor dot
  7826. }
  7827. return $code
  7828. }
  7829.  
  7830.  
  7831. proc Tree::_drag_and_drop { path from endItem operation type startItem } {
  7832. if {[winfo parent $from] != $path} { return }
  7833.  
  7834. set place [lindex $endItem 0]
  7835.  
  7836. switch -- $place {
  7837. "node" {
  7838. set node   [lindex $endItem 1]
  7839. set parent [$path parent $node]
  7840. set index  [$path index $node]
  7841. }
  7842.  
  7843. "position" {
  7844. set parent [lindex $endItem 1]
  7845. set index  [lindex $endItem 2]
  7846. }
  7847.  
  7848. default {
  7849. return
  7850. }
  7851. }
  7852.  
  7853. if {[string equal $operation "copy"]} {
  7854. set options [Widget::options $path.$startItem]
  7855. eval $path insert $idx [list $startItem#auto] $options
  7856. } else {
  7857. $path move $parent $startItem $index
  7858. }
  7859. }
  7860.  
  7861.  
  7862. proc Tree::_auto_scroll { path x y } {
  7863. Widget::getVariable $path data
  7864.  
  7865. set xmax   [winfo width  $path]
  7866. set ymax   [winfo height $path]
  7867. set scroll {}
  7868. if {$y <= 6} {
  7869. if {[lindex [$path.c yview] 0] > 0} {
  7870. set scroll [list yview -1]
  7871. DropSite::setcursor sb_up_arrow
  7872. }
  7873. } elseif {$y >= $ymax-6} {
  7874. if {[lindex [$path.c yview] 1] < 1} {
  7875. set scroll [list yview 1]
  7876. DropSite::setcursor sb_down_arrow
  7877. }
  7878. } elseif {$x <= 6} {
  7879. if {[lindex [$path.c xview] 0] > 0} {
  7880. set scroll [list xview -1]
  7881. DropSite::setcursor sb_left_arrow
  7882. }
  7883. } elseif {$x >= $xmax-6} {
  7884. if {[lindex [$path.c xview] 1] < 1} {
  7885. set scroll [list xview 1]
  7886. DropSite::setcursor sb_right_arrow
  7887. }
  7888. }
  7889.  
  7890. if {[string length $data(dnd,afterid)]
  7891. && ![string equal $data(dnd,scroll) $scroll]} {
  7892. after cancel $data(dnd,afterid)
  7893. set data(dnd,afterid) ""
  7894. }
  7895.  
  7896. set data(dnd,scroll) $scroll
  7897. if {[string length $scroll] && ![string length $data(dnd,afterid)]} {
  7898. set data(dnd,afterid) [after 200 [list Tree::_scroll $path $scroll]]
  7899. }
  7900. return $data(dnd,afterid)
  7901. }
  7902.  
  7903.  
  7904. proc Tree::_scroll { path cmd dir } {
  7905. Widget::getVariable $path data
  7906.  
  7907. if {($dir == -1 && [lindex [$path.c $cmd] 0] > 0)
  7908. || ($dir == 1  && [lindex [$path.c $cmd] 1] < 1)} {
  7909. $path.c $cmd scroll $dir units
  7910. set data(dnd,afterid) [after 100 [list Tree::_scroll $path $cmd $dir]]
  7911. } else {
  7912. set data(dnd,afterid) ""
  7913. DropSite::setcursor dot
  7914. }
  7915. }
  7916.  
  7917.  
  7918. proc Tree::_keynav {which win} {
  7919.  
  7920. set nodes {}
  7921. foreach nodeItem [$win.c find withtag node] {
  7922. set node [Tree::_get_node_name $win $nodeItem 2]
  7923. if {[Widget::cget $win.$node -selectable]} {
  7924. lappend nodes $node
  7925. }
  7926. }
  7927.  
  7928. set node [_get_current_node $win]
  7929.  
  7930. switch -exact -- $which {
  7931. "up" {
  7932. if {![string length $node]} { return }
  7933.  
  7934. set index [lsearch -exact $nodes $node]
  7935. incr index -1
  7936. if {$index >= 0} {
  7937. $win selection set [lindex $nodes $index]
  7938. _set_current_node $win [lindex $nodes $index]
  7939. $win see [lindex $nodes $index]
  7940. return
  7941. }
  7942. }
  7943.  
  7944. "down" {
  7945. if {![string length $node]} {
  7946. $win selection set [lindex $nodes 0]
  7947. _set_current_node $win [lindex $nodes 0]
  7948. $win see [lindex $nodes 0]
  7949. return
  7950. }
  7951.  
  7952. set index [lsearch -exact $nodes $node]
  7953. incr index
  7954. if {$index < [llength $nodes]} {
  7955. $win selection set [lindex $nodes $index]
  7956. _set_current_node $win [lindex $nodes $index]
  7957. $win see [lindex $nodes $index]
  7958. return
  7959. }
  7960. }
  7961.  
  7962. "right" {
  7963. if {![string length $node]} { return }
  7964.  
  7965. if {[Widget::getoption $path.$node -open]} {
  7966. if { [llength [$win nodes $node]] } {
  7967. set index [lsearch -exact $nodes $node]
  7968. incr index
  7969. if {$index < [llength $nodes]} {
  7970. $win selection set [lindex $nodes $index]
  7971. _set_current_node $win [lindex $nodes $index]
  7972. $win see [lindex $nodes $index]
  7973. return
  7974. }
  7975. }
  7976. } else {
  7977. $win itemconfigure $node -open 1
  7978. if {[llength [set cmd [Widget::getoption $win -opencmd]]]} {
  7979. uplevel \#0 $cmd [list $node]
  7980. }
  7981. return
  7982. }
  7983. }
  7984.  
  7985. "left" {
  7986. if {![string length $node]} { return }
  7987.  
  7988. if {[Widget::getoption $path.$node -open]} {
  7989. $win itemconfigure $node -open 0
  7990. if {[llength [set cmd [Widget::getoption $win -closecmd]]]} {
  7991. uplevel \#0 $cmd [list $node]
  7992. }
  7993. return
  7994. } else {
  7995. set parent [$win parent $node]
  7996. if {[string equal $parent "root"]} {
  7997. set parent $node
  7998. } else {
  7999. while {![$win itemcget $parent -selectable]} {
  8000. set parent [$win parent $parent]
  8001. if {[string equal $parent "root"]} {
  8002. set parent $node
  8003. break
  8004. }
  8005. }
  8006. }
  8007. $win selection set $parent
  8008. _set_current_node $win $parent
  8009. $win see $parent
  8010. return
  8011. }
  8012. }
  8013.  
  8014. "space" {
  8015. if {[string length $node]} {
  8016. Tree::toggle $path $node
  8017. }
  8018. }
  8019. }
  8020. }
  8021.  
  8022.  
  8023. proc Tree::_get_current_node {win} {
  8024. if {[info exists selectTree::selectCursor($win)]} {
  8025. set result $selectTree::selectCursor($win)
  8026. } elseif {[llength [set selList [$win selection get]]]} {
  8027. set result [lindex $selList 0]
  8028. } else {
  8029. set result ""
  8030. }
  8031. return $result
  8032. }
  8033.  
  8034.  
  8035. proc Tree::_set_current_node {win node} {
  8036. if {[info exists selectTree::selectCursor($win)]} {
  8037. set selectTree::selectCursor($win) $node
  8038. }
  8039. return
  8040. }
  8041.  
  8042.  
  8043. proc Tree::_get_node_name {path {item current} {tagindex end-1}} {
  8044. return [string range [lindex [$path.c gettags $item] $tagindex] 2 end]
  8045. }
  8046.  
  8047. proc Tree::_get_node_padx {path node} {
  8048. set padx [Widget::getoption $path.$node -padx]
  8049. if {$padx < 0} { set padx [Widget::getoption $path -padx] }
  8050. return $padx
  8051. }
  8052.  
  8053. proc Tree::_get_node_deltax {path node} {
  8054. set deltax [Widget::getoption $path.$node -deltax]
  8055. if {$deltax < 0} { set deltax [Widget::getoption $path -deltax] }
  8056. return $deltax
  8057. }
  8058.  
  8059.  
  8060. proc Tree::_get_node_tags {path node {tags ""}} {
  8061. eval [linsert $tags 0 lappend list TreeItemSentinal]
  8062. if {[Widget::getoption $path.$node -helptext] == ""} { return $list }
  8063.  
  8064. switch -- [Widget::getoption $path.$node -helptype] {
  8065. balloon {
  8066. lappend list BwHelpBalloon
  8067. }
  8068. variable {
  8069. lappend list BwHelpVariable
  8070. }
  8071. }
  8072. return $list
  8073. }
  8074.  
  8075. proc Tree::_set_help { path node } {
  8076. Widget::getVariable $path help
  8077.  
  8078. set item $path.$node
  8079. set opts [list -helptype -helptext -helpvar]
  8080. foreach {cty ctx cv} [eval [linsert $opts 0 Widget::hasChangedX $item]] break
  8081. set text [Widget::getoption $item -helptext]
  8082.  
  8083. if { (![info exists help($node)] && $text != "") || $cty || $ctx || $cv } {
  8084. set help($node) 1
  8085. set type [Widget::getoption $item -helptype]
  8086. switch $type {
  8087. balloon {
  8088. DynamicHelp::register $path.c balloon n:$node $text
  8089. DynamicHelp::register $path.c balloon i:$node $text
  8090. DynamicHelp::register $path.c balloon b:$node $text
  8091. }
  8092. variable {
  8093. set var [Widget::getoption $item -helpvar]
  8094. DynamicHelp::register $path.c variable n:$node $var $text
  8095. DynamicHelp::register $path.c variable i:$node $var $text
  8096. DynamicHelp::register $path.c variable b:$node $var $text
  8097. }
  8098. }
  8099. }
  8100. }
  8101.  
  8102. proc Tree::_mouse_select { path cmd args } {
  8103. eval [linsert $args 0 selection $path $cmd]
  8104. switch -- $cmd {
  8105. "add" - "clear" - "remove" - "set" - "toggle" {
  8106. event generate $path <<TreeSelect>>
  8107. }
  8108. }
  8109. }
  8110.  
  8111.  
  8112. proc Tree::_node_name { path node } {
  8113. set map [list & _ | _ ^ _ ! _]
  8114. return  [string map $map $node]
  8115. }
  8116.  
  8117.  
  8118. proc Tree::_get_option { path node option {default ""} } {
  8119. return [Widget::getOption $option $default $path.$node $path]
  8120. }
  8121.  
  8122.  
  8123. proc Tree::_destroy { path } {
  8124. Widget::getVariable $path data
  8125.  
  8126. if {[string length $data(upd,afterid)]} {
  8127. after cancel $data(upd,afterid)
  8128. }
  8129.  
  8130. if {[string length $data(dnd,afterid)]} {
  8131. after cancel $data(dnd,afterid)
  8132. }
  8133.  
  8134. _subdelete $path [lrange $data(root) 1 end]
  8135. Widget::destroy $path
  8136. }
  8137.  
  8138.  
  8139. namespace eval ListBox {
  8140. Widget::define ListBox listbox DragSite DropSite DynamicHelp
  8141.  
  8142. namespace eval Item {
  8143. Widget::declare ListBox::Item {
  8144. {-indent     Int        0   0 "%d >= 0"}
  8145. {-text       String     ""  0}
  8146. {-font       String     ""  0}
  8147. {-foreground Color2     ""  0}
  8148. {-image      String     ""  0}
  8149. {-window     String     ""  0}
  8150. {-data       String     ""  0}
  8151.  
  8152. {-fg         Synonym    -foreground}
  8153. {-fill       Synonym    -foreground}
  8154. }
  8155. }
  8156.  
  8157. DynamicHelp::include ListBox::Item balloon
  8158.  
  8159. Widget::tkinclude ListBox canvas .c  remove {
  8160. -insertwidth -insertbackground -insertborderwidth -insertofftime
  8161. -insertontime -selectborderwidth -closeenough -confine -scrollregion
  8162. -xscrollincrement -yscrollincrement -width -height -bg -background
  8163. -fg -foreground -selectbackground -selectforeground
  8164. } initialize {
  8165. -relief sunken -borderwidth 2 -takefocus 1
  8166. -highlightthickness 0 -width 200
  8167. }
  8168.  
  8169. DragSite::include ListBox "LISTBOX_ITEM" 1
  8170. DropSite::include ListBox {
  8171. LISTBOX_ITEM {copy {} move {}}
  8172. }
  8173.  
  8174. Widget::declare ListBox {
  8175. {-deltax           Int        10                        0 "%d >= 0"}
  8176. {-deltay           Int        15                        0 "%d >= 0"}
  8177. {-padx             Int        20                        0 "%d >= 0"}
  8178. {-foreground       Color      "SystemButtonText"        0 listbox}
  8179. {-background       Color      "SystemWindow"            0 listbox}
  8180. {-selectbackground Color      "SystemHighlight"         0 listbox}
  8181. {-selectforeground Color      "SystemHighlightText"     0 listbox}
  8182. {-font             String     "TkTextFont"              0 listbox}
  8183. {-width            TkResource ""                        0 listbox}
  8184. {-height           TkResource ""                        0 listbox}
  8185. {-redraw           Boolean    1                         0}
  8186. {-multicolumn      Boolean    0                         0}
  8187. {-dropovermode     Flag       "wpi"                     0 "wpi"}
  8188. {-selectmode       Enum       none                      1
  8189. {none single multiple}}
  8190. {-dropcmd          String     "ListBox::_drag_and_drop" 0}
  8191. {-autofocus        Boolean    1                         1}
  8192. {-selectfill       Boolean    0                         1}
  8193.  
  8194. {-sortargs         String     ""                        0}
  8195. {-sortinsert       Boolean    0                         0}
  8196.  
  8197. {-fg               Synonym    -foreground}
  8198. {-bg               Synonym    -background}
  8199. }
  8200.  
  8201. bind ListBox <FocusIn>   [list after idle {BWidget::refocus %W %W.c}]
  8202. bind ListBox <Destroy>   [list ListBox::_destroy %W]
  8203. bind ListBox <Configure> [list ListBox::_resize  %W]
  8204. bind ListBoxFocus <1>    [list focus %W]
  8205. bind ListBox <Key-Up>    [list ListBox::_keyboard_navigation %W -1]
  8206. bind ListBox <Key-Down>  [list ListBox::_keyboard_navigation %W  1]
  8207.  
  8208. BWidget::bindMouseWheel ListBoxCanvas
  8209.  
  8210. variable _edit
  8211. }
  8212.  
  8213.  
  8214. proc ListBox::create { path args } {
  8215. Widget::initArgs ListBox $args maps
  8216.  
  8217. frame $path -class ListBox -bd 0 -highlightthickness 0 -relief flat  -takefocus 0
  8218.  
  8219. if {[package vsatisfies $::tk_version 8.4]} {
  8220. $path configure -padx 0 -pady 0
  8221. }
  8222.  
  8223. Widget::initFromODB ListBox $path $maps(ListBox)
  8224.  
  8225. Widget::getVariable $path data
  8226.  
  8227. set data(nrows) -1
  8228.  
  8229. set data(items)    {}
  8230. set data(anchor)   ""
  8231. set data(selitems) {}
  8232.  
  8233. set data(upd,level)   0
  8234. set data(upd,afterid) ""
  8235. set data(upd,level)   0
  8236. set data(upd,delete)  {}
  8237.  
  8238. set data(dnd,scroll)   ""
  8239. set data(dnd,afterid)  ""
  8240. set data(dnd,item)     ""
  8241.  
  8242. eval [list canvas $path.c] $maps(.c) -xscrollincrement 8  -background [Widget::getoption $path -background]
  8243. pack $path.c -expand yes -fill both
  8244.  
  8245. DragSite::setdrag $path $path.c ListBox::_init_drag_cmd  [Widget::cget $path -dragendcmd] 1
  8246. DropSite::setdrop $path $path.c ListBox::_over_cmd ListBox::_drop_cmd 1
  8247.  
  8248. Widget::create ListBox $path
  8249.  
  8250. set w  [Widget::cget $path -width]
  8251. set h  [Widget::cget $path -height]
  8252. set dy [Widget::cget $path -deltay]
  8253. $path.c configure -width [expr {$w*8}] -height [expr {$h*$dy}]  -yscrollincrement $dy
  8254.  
  8255. set bindtags [bindtags $path.c]
  8256. set bindtags [linsert $bindtags 1 $path ListBoxCanvas]
  8257.  
  8258. if {[Widget::cget $path -autofocus]} {
  8259. lappend bindtags ListBoxFocus
  8260. }
  8261. bindtags $path.c $bindtags
  8262.  
  8263. bind $path.c <Key-Up>   {ListBox::_keyboard_navigation [winfo parent %W] -1}
  8264. bind $path.c <Key-Down> {ListBox::_keyboard_navigation [winfo parent %W] 1}
  8265.  
  8266. if {![string equal [Widget::getoption $path -selectmode] "none"]} {
  8267. set cmd ListBox::_multiple_select
  8268. $path bindText <Button-1>          [list $cmd $path none]
  8269. $path bindText <Shift-Button-1>    [list $cmd $path shift]
  8270. $path bindText <Control-Button-1>  [list $cmd $path control]
  8271.  
  8272. $path bindImage <Button-1>         [list $cmd $path none]
  8273. $path bindImage <Shift-Button-1>   [list $cmd $path shift]
  8274. $path bindImage <Control-Button-1> [list $cmd $path control]
  8275. }
  8276.  
  8277. return $path
  8278. }
  8279.  
  8280.  
  8281. proc ListBox::cget { path option } {
  8282. return [Widget::cget $path $option]
  8283. }
  8284.  
  8285.  
  8286. proc ListBox::configure { path args } {
  8287. set res [Widget::configure $path $args]
  8288.  
  8289. set chdy [Widget::hasChanged $path -deltay dy]
  8290.  
  8291. set ch1 [expr {$chdy
  8292. || [Widget::hasChanged $path -padx val]
  8293. || [Widget::hasChanged $path -font font]
  8294. || [Widget::hasChanged $path -multicolumn val]
  8295. || [Widget::hasChanged $path -foreground fg]}]
  8296.  
  8297. set ch2 [expr {[Widget::hasChanged $path -selectbackground val] |
  8298. [Widget::hasChanged $path -selectforeground val]}]
  8299.  
  8300. if {[Widget::hasChanged $path -height h]} {
  8301. $path.c configure -height [expr {$h*$dy}]
  8302. }
  8303.  
  8304. if {[Widget::hasChanged $path -width w]} {
  8305. $path.c configure -width [expr {$w*8}]
  8306. }
  8307.  
  8308. if {[Widget::hasChanged $path -background bg]} {
  8309. $path.c configure -background $bg
  8310. $path.c itemconfigure box -fill $bg
  8311. }
  8312.  
  8313. if {$chdy} {
  8314. $path.c configure -yscrollincrement $dy
  8315. }
  8316.  
  8317. if {$ch1} {
  8318. _redraw_idle $path 2
  8319. } elseif {$ch2} {
  8320. _redraw_idle $path 1
  8321. }
  8322.  
  8323. if {[Widget::hasChanged $path -redraw bool] && $bool} {
  8324. Widget::getVariable $path data
  8325. set lvl $data(upd,level)
  8326. set data(upd,level) 0
  8327. _redraw_idle $path $lvl
  8328. }
  8329.  
  8330. set force [Widget::hasChanged $path -dragendcmd dragend]
  8331. DragSite::setdrag $path $path.c ListBox::_init_drag_cmd $dragend $force
  8332. DropSite::setdrop $path $path.c ListBox::_over_cmd ListBox::_drop_cmd
  8333.  
  8334. return $res
  8335. }
  8336.  
  8337.  
  8338. proc ListBox::activate { path index } {
  8339.  
  8340. }
  8341.  
  8342.  
  8343. proc ListBox::insert { path index item args } {
  8344. Widget::getVariable $path data
  8345.  
  8346. set item [Widget::nextIndex $path $item]
  8347.  
  8348. if {[info exists data(item,$item)]} {
  8349. return -code error "item \"$item\" already exists"
  8350. }
  8351.  
  8352. Widget::init ListBox::Item $path.$item $args
  8353.  
  8354. if {[string equal $index "end"]} {
  8355. lappend data(items) $item
  8356. } else {
  8357. set data(items) [linsert $data(items) $index $item]
  8358. }
  8359.  
  8360. set data(item,$item) 0
  8361. set data(upd,create,$item) $item
  8362.  
  8363. if {[Widget::getoption $path -sortinsert]} {
  8364. ListBox::_sort_idle $path
  8365. } else {
  8366. ListBox::_redraw_idle $path 2
  8367. }
  8368.  
  8369. return $item
  8370. }
  8371.  
  8372. proc ListBox::multipleinsert { path index args } {
  8373. Widget::getVariable $path data
  8374.  
  8375.  
  8376. if {[llength $args] == 1} {
  8377. set args [lindex $args 0]
  8378. }
  8379.  
  8380. set count 0
  8381. foreach {item iargs} $args {
  8382. if { [lsearch -exact $data(items) $item] != -1 } {
  8383. return -code error "item \"$item\" already exists"
  8384. }
  8385.  
  8386. if {$count==0} {
  8387. Widget::init ListBox::Item $path.$item $iargs
  8388. set firstpath $path.$item
  8389. } else {
  8390. Widget::copyinit ListBox::Item $firstpath $path.$item $iargs
  8391. }
  8392.  
  8393. set data(items) [linsert $data(items) $index $item]
  8394. set data(upd,create,$item) $item
  8395.  
  8396. incr count
  8397. }
  8398.  
  8399. _redraw_idle $path 2
  8400. return $item
  8401. }
  8402.  
  8403.  
  8404. proc ListBox::itemcget { path item option } {
  8405. return [Widget::cget $path.$item $option]
  8406. }
  8407.  
  8408.  
  8409. proc ListBox::itemconfigure { path item args } {
  8410. Widget::getVariable $path data
  8411.  
  8412. if {![info exists data(item,$item)]} {
  8413. return -code error "item \"$item\" does not exist"
  8414. }
  8415.  
  8416. set oldind [Widget::getoption $path.$item -indent]
  8417.  
  8418. set res   [Widget::configure $path.$item $args]
  8419. set chind [Widget::hasChanged $path.$item -indent indent]
  8420. set chw   [Widget::hasChanged $path.$item -window win]
  8421. set chi   [Widget::hasChanged $path.$item -image  img]
  8422. set cht   [Widget::hasChanged $path.$item -text txt]
  8423. set chf   [Widget::hasChanged $path.$item -font fnt]
  8424. set chfg  [Widget::hasChanged $path.$item -foreground fg]
  8425. set idn   [lindex $data(item,$item) 0]
  8426.  
  8427. _set_help $path $item
  8428.  
  8429. if {![string length $idn]} {
  8430. _redraw_idle $path 2
  8431. return $res
  8432. }
  8433.  
  8434. set oldb   [$path.c bbox $idn]
  8435. set coords [$path.c coords $idn]
  8436. set padx   [Widget::getoption $path -padx]
  8437. set x0     [expr {[lindex $coords 0]-$padx-$oldind+$indent}]
  8438. set y0     [lindex $coords 1]
  8439.  
  8440. if {$chw || $chi} {
  8441. set idi  [$path.c find withtag i:$item]
  8442. set type [lindex [$path.c gettags $idi] 0]
  8443. if { [string length $win] } {
  8444. if { [string equal $type "win"] } {
  8445. $path.c itemconfigure $idi -window $win
  8446. } else {
  8447. $path.c delete $idi
  8448. $path.c create window $x0 $y0 -window $win -anchor w  -tags [list win i:$item]
  8449. }
  8450. } elseif { [string length $img] } {
  8451. if { [string equal $type "img"] } {
  8452. $path.c itemconfigure $idi -image $img
  8453. } else {
  8454. $path.c delete $idi
  8455. $path.c create image $x0 $y0 -image $img -anchor w  -tags [list img i:$item]
  8456. }
  8457. } else {
  8458. $path.c delete $idi
  8459. }
  8460. }
  8461.  
  8462. if {$cht || $chf || $chfg} {
  8463. set fnt [_getoption $path $item -font]
  8464. set fg  [_getoption $path $item -foreground]
  8465. $path.c itemconfigure $idn -text $txt -font $fnt -fill $fg
  8466. _redraw_idle $path 1
  8467. }
  8468.  
  8469. if {$chind} {
  8470. $path.c coords $idn [expr {$x0+$padx}] $y0
  8471. $path.c coords i:$item $x0 $y0
  8472. _redraw_idle $path 1
  8473. }
  8474.  
  8475. if {[Widget::getoption $path -multicolumn] && ($cht || $chf || $chind)} {
  8476. set bbox [$path.c bbox $idn]
  8477. if {[lindex $bbox 2] > [lindex $oldb 2]} {
  8478. _redraw_idle $path 2
  8479. }
  8480. }
  8481.  
  8482. return $res
  8483. }
  8484.  
  8485.  
  8486. proc ListBox::bindText { path event script } {
  8487. if {[string length $script]} {
  8488. set map    [list %W $path]
  8489. set script [string map $map $script]
  8490. append script " \[ListBox::_get_current [list $path]\]"
  8491. }
  8492. $path.c bind "click" $event $script
  8493. }
  8494.  
  8495.  
  8496. proc ListBox::bindImage { path event script } {
  8497. if {[string length $script]} {
  8498. set map    [list %W $path]
  8499. set script [string map $map $script]
  8500. append script " \[ListBox::_get_current [list $path]\]"
  8501. }
  8502. $path.c bind "img" $event $script
  8503. }
  8504.  
  8505.  
  8506. proc ListBox::delete { path args } {
  8507. Widget::getVariable $path data
  8508.  
  8509. foreach litems $args {
  8510. foreach item $litems {
  8511. if {[set idx [lsearch -exact $data(items) $item]] != -1} {
  8512. set data(items) [lreplace $data(items) $idx $idx]
  8513. Widget::destroy $path.$item 0
  8514. unset data(item,$item)
  8515. if {[info exists data(upd,create,$item)]} {
  8516. unset data(upd,create,$item)
  8517. } else {
  8518. lappend data(upd,delete) $item
  8519. }
  8520. }
  8521. }
  8522. }
  8523.  
  8524. set sel $data(selitems)
  8525. set data(selitems) {}
  8526. eval [list ListBox::selection $path set] $sel
  8527. _redraw_idle $path 2
  8528.  
  8529. return
  8530. }
  8531.  
  8532.  
  8533. proc ListBox::clear { path } {
  8534. eval [list ListBox::delete $path] [ListBox::items $path]
  8535. }
  8536.  
  8537.  
  8538. proc ListBox::move { path item index } {
  8539. Widget::getVariable $path data
  8540.  
  8541. if {![info exists data(item,$item)]} {
  8542. return -code error "item \"$item\" does not exist"
  8543. }
  8544.  
  8545. set idx [lsearch -exact $data(items) $item]
  8546. set data(items) [linsert [lreplace $data(items) $idx $idx] $index $item]
  8547.  
  8548. _redraw_idle $path 2
  8549. }
  8550.  
  8551.  
  8552. proc ListBox::reorder { path neworder } {
  8553. Widget::getVariable $path data
  8554.  
  8555. set data(items) [BWidget::lreorder $data(items) $neworder]
  8556. _redraw_idle $path 2
  8557. }
  8558.  
  8559.  
  8560. proc ListBox::selection { path cmd args } {
  8561. Widget::getVariable $path data
  8562.  
  8563. switch -- $cmd {
  8564. "add" {
  8565. foreach item $args {
  8566. if { [lsearch -exact $data(selitems) $item] == -1 } {
  8567. if { [lsearch -exact $data(items) $item] != -1 } {
  8568. lappend data(selitems) $item
  8569. }
  8570. }
  8571. }
  8572. }
  8573.  
  8574. "clear" {
  8575. set data(selitems) {}
  8576. }
  8577.  
  8578. "get" {
  8579. return $data(selitems)
  8580. }
  8581.  
  8582. "includes" {
  8583. return [expr {[lsearch -exact $data(selitems) $args] != -1}]
  8584. }
  8585.  
  8586. "range" {
  8587. foreach {item1 item2} $args {break}
  8588.  
  8589. if {![info exists data(item,$item1)]} {
  8590. return -code error "item \"$item1\" does not exist"
  8591. }
  8592.  
  8593. if {![info exists data(item,$item2)]} {
  8594. return -code error "item \"$item2\" does not exist"
  8595. }
  8596.  
  8597. set index1  [ListBox::index $path $item1]
  8598. set index2  [ListBox::index $path $item2]
  8599. set indexes [list $index1 $index2]
  8600. if {$index1 > $index2} {
  8601. set indexes [list $index2 $index1]
  8602. }
  8603.  
  8604. set data(selitems) [eval [list ListBox::items $path] $indexes]
  8605. }
  8606.  
  8607. "remove" {
  8608. foreach item $args {
  8609. if {[set idx [lsearch -exact $data(selitems) $item]] != -1} {
  8610. set data(selitems) [lreplace $data(selitems) $idx $idx]
  8611. }
  8612. }
  8613. }
  8614.  
  8615. "set" {
  8616. set data(selitems) {}
  8617. foreach item $args {
  8618. if { [lsearch -exact $data(selitems) $item] == -1 } {
  8619. if { [lsearch -exact $data(items) $item] != -1 } {
  8620. lappend data(selitems) $item
  8621. }
  8622. }
  8623. }
  8624. }
  8625.  
  8626. "toggle" {
  8627. foreach item $args {
  8628. if {[set idx [lsearch -exact $data(selitems) $item]] != -1} {
  8629. set data(selitems) [lreplace $data(selitems) $idx $idx]
  8630. } else {
  8631. lappend data(selitems) $item
  8632. }
  8633. }
  8634. }
  8635.  
  8636. default {
  8637. return
  8638. }
  8639. }
  8640.  
  8641. _redraw_idle $path 1
  8642. }
  8643.  
  8644.  
  8645. proc ListBox::exists { path item } {
  8646. Widget::getVariable $path data
  8647. return [info exists data(item,$item)]
  8648. }
  8649.  
  8650.  
  8651. proc ListBox::index { path item } {
  8652. Widget::getVariable $path data
  8653.  
  8654. switch -glob -- $item {
  8655. "active" {
  8656. return [ListBox::selection $path get]
  8657. }
  8658.  
  8659. "end" {
  8660. return [llength $data(items)]
  8661. }
  8662.  
  8663. "@*" {
  8664. return [ListBox::find $path $item]
  8665. }
  8666.  
  8667. default {
  8668. return [lsearch -exact $data(items) $item]
  8669. }
  8670. }
  8671. }
  8672.  
  8673.  
  8674. proc ListBox::find { path findInfo {confine ""} } {
  8675. Widget::getVariable $path data
  8676.  
  8677. if {[regexp -- {^@([0-9]+),([0-9]+)$} $findInfo match x y]} {
  8678. set x [$path.c canvasx $x]
  8679. set y [$path.c canvasy $y]
  8680. } elseif {[regexp -- {^[0-9]+$} $findInfo lineNumber]} {
  8681. set dy [Widget::cget $path -deltay]
  8682. set y  [expr {$dy*($lineNumber+0.5)}]
  8683. set confine ""
  8684. } else {
  8685. return -code error "invalid find spec \"$findInfo\""
  8686. }
  8687.  
  8688. set found 0
  8689. set xi    0
  8690. foreach xs $data(xlist) {
  8691. if {$x <= $xs} {
  8692. foreach id [$path.c find overlapping $xi $y $xs $y] {
  8693. set ltags [$path.c gettags $id]
  8694. set item  [lindex $ltags 0]
  8695. if { [string equal $item "item"] ||
  8696. [string equal $item "img"]  ||
  8697. [string equal $item "win"] } {
  8698. set item [string range [lindex $ltags 1] 2 end]
  8699. set found 1
  8700. break
  8701. }
  8702. }
  8703. break
  8704. }
  8705. set  xi  $xs
  8706. }
  8707.  
  8708. if {$found} {
  8709. if {[string equal $confine "confine"]} {
  8710. set xi [expr {[lindex [$path.c coords n:$item] 0]-[Widget::getoption $path -padx]}]
  8711. set xs [lindex [$path.c bbox n:$item] 2]
  8712. if {$x >= $xi && $x <= $xs} {
  8713. return $item
  8714. }
  8715. } else {
  8716. return $item
  8717. }
  8718. }
  8719. return ""
  8720. }
  8721.  
  8722.  
  8723. proc ListBox::item { path first {last ""} } {
  8724. Widget::getVariable $path data
  8725.  
  8726. if { ![string length $last] } {
  8727. return [lindex $data(items) $first]
  8728. } else {
  8729. return [lrange $data(items) $first $last]
  8730. }
  8731. }
  8732.  
  8733.  
  8734. proc ListBox::items { path {first ""} {last ""}} {
  8735. Widget::getVariable $path data
  8736. if {![string length $first]} { return $data(items) }
  8737. if {![string length $last]}  { return [lindex $data(items) $first] }
  8738. return [lrange $data(items) $first $last]
  8739. }
  8740.  
  8741.  
  8742. proc ListBox::see { path item } {
  8743. Widget::getVariable $path data
  8744.  
  8745. if {[Widget::getoption $path -redraw] && $data(upd,afterid) != ""} {
  8746. after cancel $data(upd,afterid)
  8747. _redraw_listbox $path
  8748. }
  8749. set idn [$path.c find withtag n:$item]
  8750. if {[string length $idn]} {
  8751. ListBox::_see $path $idn right
  8752. ListBox::_see $path $idn left
  8753. }
  8754. }
  8755.  
  8756.  
  8757. proc ListBox::edit { path item text {verifycmd ""} {clickres 0} {select 1}} {
  8758. variable _edit
  8759. Widget::getVariable $path data
  8760.  
  8761. if { [Widget::getoption $path -redraw] && $data(upd,afterid) != "" } {
  8762. after cancel $data(upd,afterid)
  8763. _redraw_listbox $path
  8764. }
  8765. set idn [$path.c find withtag n:$item]
  8766. if { $idn != "" } {
  8767. ListBox::_see $path $idn right
  8768. ListBox::_see $path $idn left
  8769.  
  8770. set oldfg  [$path.c itemcget $idn -fill]
  8771. set sbg    [Widget::cget $path -selectbackground]
  8772. set coords [$path.c coords $idn]
  8773. set x      [lindex $coords 0]
  8774. set y      [lindex $coords 1]
  8775. set ht     [$path.c cget -highlightthickness]
  8776. set bd     [expr {[$path.c cget -borderwidth] + $ht}]
  8777. set w      [expr {[winfo width $path] - 2 * $bd}]
  8778. set wmax   [expr {[$path.c canvasx $w] - $x}]
  8779.  
  8780. $path.c itemconfigure $idn    -fill [Widget::cget $path -background]
  8781. $path.c itemconfigure s:$item -fill {} -outline {}
  8782.  
  8783. set _edit(text) $text
  8784. set _edit(wait) 0
  8785.  
  8786. set frame  [frame $path.edit  -relief flat -borderwidth 0 -highlightthickness 0  -background [Widget::cget $path -background]]
  8787.  
  8788. set ent    [entry $frame.edit  -width              0      -relief             solid  -borderwidth        1      -highlightthickness 0      -foreground         [_getoption $path $item -foreground]  -background         [Widget::cget $path -background]  -selectforeground   [Widget::cget $path -selectforeground]  -selectbackground   $sbg   -font               [_getoption $path $item -font]  -textvariable       ListBox::_edit(text)]
  8789. pack $ent -ipadx 8 -anchor w
  8790.  
  8791. set idw [$path.c create window $x $y -window $frame -anchor w]
  8792. trace variable ListBox::_edit(text) w  [list ListBox::_update_edit_size $path $ent $idw $wmax]
  8793. tkwait visibility $ent
  8794. grab  $frame
  8795. BWidget::focus set $ent
  8796. _update_edit_size $path $ent $idw $wmax
  8797. update
  8798.  
  8799. if {$select} {
  8800. $ent selection range 0 end
  8801. $ent icursor end
  8802. $ent xview end
  8803. }
  8804.  
  8805. bindtags $ent [list $ent Entry]
  8806. bind $ent <Escape> {set ListBox::_edit(wait) 0}
  8807. bind $ent <Return> {set ListBox::_edit(wait) 1}
  8808.  
  8809. if {$clickres == 0 || $clickres == 1} {
  8810. bind $frame <Button>  [list set ListBox::_edit(wait) $clickres]
  8811. }
  8812.  
  8813. set ok 0
  8814. while {!$ok} {
  8815. tkwait variable ListBox::_edit(wait)
  8816. if { !$_edit(wait) || [llength $verifycmd]==0 ||
  8817. [uplevel \#0 $verifycmd [list $_edit(text)]] } {
  8818. set ok 1
  8819. }
  8820. }
  8821.  
  8822. trace vdelete ListBox::_edit(text) w  [list ListBox::_update_edit_size $path $ent $idw $wmax]
  8823. grab release $frame
  8824. BWidget::focus release $ent
  8825. destroy $frame
  8826. $path.c delete $idw
  8827. $path.c itemconfigure $idn    -fill $oldfg
  8828. $path.c itemconfigure s:$item -fill $sbg -outline $sbg
  8829.  
  8830. if {$_edit(wait)} {
  8831. return $_edit(text)
  8832. }
  8833. }
  8834. }
  8835.  
  8836.  
  8837. proc ListBox::xview { path args } {
  8838. return [eval [linsert $args 0 $path.c xview]]
  8839. }
  8840.  
  8841.  
  8842. proc ListBox::yview { path args } {
  8843. return [eval [linsert $args 0 $path.c yview]]
  8844. }
  8845.  
  8846.  
  8847. proc ListBox::getcanvas { path } {
  8848. return $path.c
  8849. }
  8850.  
  8851.  
  8852. proc ListBox::curselection { path } {
  8853. return [$path selection get]
  8854. }
  8855.  
  8856.  
  8857. proc ListBox::sort { path } {
  8858. Widget::getVariable $path data
  8859.  
  8860. foreach item $data(items) {
  8861. lappend list [list [Widget::getoption $path.$item -text] $item]
  8862. }
  8863.  
  8864. set data(items) [list]
  8865. foreach pair [eval lsort [Widget::getoption $path -sortargs] [list $list]] {
  8866. lappend data(items) [lindex $pair 1]
  8867. }
  8868.  
  8869. if {[info exists data(sort,afterid)]} {
  8870. unset data(sort,afterid)
  8871. }
  8872.  
  8873. _redraw_idle $path 2
  8874. }
  8875.  
  8876.  
  8877. proc ListBox::_sort_idle { path } {
  8878. Widget::getVariable $path data
  8879.  
  8880. if {![info exists data(sort,afterid)]} {
  8881. set data(sort,afterid) [after idle [list ListBox::sort $path]]
  8882. }
  8883. }
  8884.  
  8885.  
  8886. proc ListBox::_update_edit_size { path entry idw wmax args } {
  8887. set entw [winfo reqwidth $entry]
  8888. if { $entw >= $wmax } {
  8889. $path.c itemconfigure $idw -width $wmax
  8890. } else {
  8891. $path.c itemconfigure $idw -width 0
  8892. }
  8893. }
  8894.  
  8895.  
  8896. proc ListBox::_getoption { path item option } {
  8897. set value [Widget::getoption $path.$item $option]
  8898. if {![string length $value]} {
  8899. set value [Widget::getoption $path $option]
  8900. }
  8901. return $value
  8902. }
  8903.  
  8904.  
  8905. proc ListBox::_destroy { path } {
  8906. Widget::getVariable $path data
  8907.  
  8908. if {$data(upd,afterid) != ""} {
  8909. after cancel $data(upd,afterid)
  8910. }
  8911.  
  8912. if {$data(dnd,afterid) != ""} {
  8913. after cancel $data(dnd,afterid)
  8914. }
  8915.  
  8916. foreach item $data(items) {
  8917. Widget::destroy $path.$item 0
  8918. }
  8919.  
  8920. Widget::destroy $path
  8921. }
  8922.  
  8923.  
  8924. proc ListBox::_see { path idn side } {
  8925. set bbox [$path.c bbox $idn]
  8926. set scrl [$path.c cget -scrollregion]
  8927.  
  8928. set ymax [lindex $scrl 3]
  8929. set dy   [$path.c cget -yscrollincrement]
  8930. set yv   [$path.c yview]
  8931. set yv0  [expr {round([lindex $yv 0]*$ymax/$dy)}]
  8932. set yv1  [expr {round([lindex $yv 1]*$ymax/$dy)}]
  8933. set y    [expr {int([lindex [$path.c coords $idn] 1]/$dy)}]
  8934. if { $y < $yv0 } {
  8935. $path.c yview scroll [expr {$y-$yv0}] units
  8936. } elseif { $y >= $yv1 } {
  8937. $path.c yview scroll [expr {$y-$yv1+1}] units
  8938. }
  8939.  
  8940. set xmax [lindex $scrl 2]
  8941. set dx   [$path.c cget -xscrollincrement]
  8942. set xv   [$path.c xview]
  8943. if { [string equal $side "right"] } {
  8944. set xv1 [expr {round([lindex $xv 1]*$xmax/$dx)}]
  8945. set x1  [expr {int([lindex $bbox 2]/$dx)}]
  8946. if { $x1 >= $xv1 } {
  8947. $path.c xview scroll [expr {$x1-$xv1+1}] units
  8948. }
  8949. } else {
  8950. set xv0 [expr {round([lindex $xv 0]*$xmax/$dx)}]
  8951. set x0  [expr {int([lindex $bbox 0]/$dx)}]
  8952. if { $x0 < $xv0 } {
  8953. $path.c xview scroll [expr {$x0-$xv0}] units
  8954. }
  8955. }
  8956. }
  8957.  
  8958.  
  8959. proc ListBox::_update_scrollregion { path } {
  8960. set bd   [$path.c cget -borderwidth]
  8961. set ht   [$path.c cget -highlightthickness]
  8962. set bd   [expr {2*($bd + $ht)}]
  8963. set w    [expr {[winfo width  $path] - $bd}]
  8964. set h    [expr {[winfo height $path] - $bd}]
  8965. set xinc [$path.c cget -xscrollincrement]
  8966. set yinc [$path.c cget -yscrollincrement]
  8967. set bbox [$path.c bbox item win img]
  8968. if { [llength $bbox] } {
  8969. set xs [lindex $bbox 2]
  8970. set ys [lindex $bbox 3]
  8971.  
  8972. if { $w < $xs } {
  8973. set w [expr {int($xs)}]
  8974. if { [set r [expr {$w % $xinc}]] } {
  8975. set w [expr {$w+$xinc-$r}]
  8976. }
  8977. }
  8978. if { $h < $ys } {
  8979. set h [expr {int($ys)}]
  8980. if { [set r [expr {$h % $yinc}]] } {
  8981. set h [expr {$h+$yinc-$r}]
  8982. }
  8983. }
  8984. }
  8985.  
  8986. $path.c configure -scrollregion [list 0 0 $w $h]
  8987. }
  8988.  
  8989.  
  8990. proc ListBox::_update_select_fill { path } {
  8991. Widget::getVariable $path data
  8992.  
  8993. set width [winfo width $path]
  8994.  
  8995. foreach item $data(items) {
  8996. set bbox [$path.c bbox [lindex $data(item,$item) 0]]
  8997. set bbox [list 0 [lindex $bbox 1] $width [lindex $bbox 3]]
  8998. $path.c coords [lindex $data(item,$item) 2] $bbox
  8999. }
  9000.  
  9001. _redraw_selection $path
  9002. }
  9003.  
  9004.  
  9005. proc ListBox::_draw_item {path item x0 x1 y bg selfill multi ww} {
  9006. set indent  [Widget::getoption $path.$item -indent]
  9007. set i [$path.c create text [expr {$x1+$indent}] $y  -text   [Widget::getoption $path.$item -text]  -fill   [_getoption        $path $item -foreground]  -font   [_getoption        $path $item -font]  -anchor w  -tags   [list item n:$item click]]
  9008.  
  9009. lappend citems $i
  9010.  
  9011. if { [set win [Widget::getoption $path.$item -window]] != "" } {
  9012. set i [$path.c create window [expr {$x0+$indent}] $y  -window $win -anchor w -tags [list win i:$item]]
  9013. lappend citems $i
  9014. } elseif { [set img [Widget::getoption $path.$item -image]] != "" } {
  9015. set i [$path.c create image [expr {$x0+$indent}] $y  -image $img -anchor w -tags [list img i:$item]]
  9016. lappend citems $i
  9017. } else {
  9018. lappend citems ""
  9019. }
  9020.  
  9021.  
  9022. if {$selfill && !$multi} {
  9023. set bbox  [$path.c bbox n:$item]
  9024. set bbox  [list 0 [lindex $bbox 1] $ww [lindex $bbox 3]]
  9025. set tags  [list box b:$item click]
  9026. set i [$path.c create rect $bbox -fill $bg -width 0 -tags $tags]
  9027. $path.c lower $i
  9028. lappend citems $i
  9029. } else {
  9030. lappend citems ""
  9031. }
  9032.  
  9033. Widget::getVariable $path data
  9034. set data(item,$item) $citems
  9035.  
  9036. _set_help $path $item
  9037. }
  9038.  
  9039.  
  9040. proc ListBox::_redraw_items { path } {
  9041. Widget::getVariable $path data
  9042.  
  9043. set cursor [$path.c cget -cursor]
  9044. $path.c configure -cursor watch
  9045. update idletasks ; # make sure watch cursor is reflected
  9046.  
  9047. set dx    [Widget::getoption $path -deltax]
  9048. set dy    [Widget::cget $path -deltay]
  9049. set padx  [Widget::getoption $path -padx]
  9050. set y0    [expr {$dy/2}]
  9051. set x0    4
  9052. set x1    [expr {$x0+$padx}]
  9053. set drawn [list]
  9054. set nitems 0
  9055. set data(xlist) [list]
  9056.  
  9057. if {[Widget::getoption $path -multicolumn]} {
  9058. set nrows $data(nrows)
  9059. } else {
  9060. set nrows [llength $data(items)]
  9061. }
  9062.  
  9063. foreach item $data(upd,delete) {
  9064. $path.c delete i:$item n:$item s:$item b:$item
  9065. }
  9066.  
  9067. set bg      [Widget::cget $path -background]
  9068. set selfill [Widget::cget $path -selectfill]
  9069. set multi   [Widget::cget $path -multicolumn]
  9070. set ww      [winfo width $path]
  9071. foreach item $data(items) {
  9072. if {[info exists data(upd,create,$item)]} {
  9073. _draw_item $path $item $x0 $x1 $y0 $bg $selfill $multi $ww
  9074. set nitem  [lindex $data(item,$item) 0]
  9075. set iitem  [lindex $data(item,$item) 1]
  9076. set bitem  [lindex $data(item,$item) 2]
  9077. unset data(upd,create,$item)
  9078. } else {
  9079. set nitem  [lindex $data(item,$item) 0]
  9080. set iitem  [lindex $data(item,$item) 1]
  9081. set bitem  [lindex $data(item,$item) 2]
  9082. set indent [Widget::getoption $path.$item -indent]
  9083. $path.c coords $nitem [list [expr {$x1+$indent}] $y0]
  9084. if {[string length $iitem]} {
  9085. $path.c coords $iitem [list [expr {$x0+$indent}] $y0]
  9086. }
  9087.  
  9088. $path.c itemconfigure $nitem  -font [ListBox::_getoption $path $item -font]  -fill [ListBox::_getoption $path $item -foreground]
  9089. }
  9090.  
  9091. incr y0 $dy
  9092. incr nitems
  9093. if {$selfill} {
  9094. lappend drawn $bitem
  9095. } else {
  9096. lappend drawn $nitem
  9097. }
  9098.  
  9099. if {$nitems == $nrows} {
  9100. set y0     [expr {$dy/2}]
  9101. set bbox   [eval [linsert $drawn 0 $path.c bbox]]
  9102. set drawn  [list]
  9103. set x0     [expr {[lindex $bbox 2]+$dx}]
  9104. set x1     [expr {$x0+$padx}]
  9105. set nitems 0
  9106. lappend data(xlist) [lindex $bbox 2]
  9107. }
  9108. }
  9109.  
  9110. if {$nitems && $nitems < $nrows} {
  9111. set bbox  [eval [linsert $drawn 0 $path.c bbox]]
  9112. lappend data(xlist) [lindex $bbox 2]
  9113. }
  9114.  
  9115. set data(upd,delete) {}
  9116. $path.c configure -cursor $cursor
  9117. }
  9118.  
  9119.  
  9120. proc ListBox::_redraw_selection { path } {
  9121. Widget::getVariable $path data
  9122.  
  9123. set selbg   [Widget::cget $path -selectbackground]
  9124. set selfg   [Widget::cget $path -selectforeground]
  9125. set selfill [Widget::getoption $path -selectfill]
  9126. set multi   [Widget::getoption $path -multicolumn]
  9127. foreach id [$path.c find withtag sel] {
  9128. set item [string range [lindex [$path.c gettags $id] 1] 2 end]
  9129. $path.c itemconfigure [lindex $data(item,$item) 0]  -fill [_getoption $path $item -foreground]
  9130. }
  9131. $path.c delete sel
  9132. if {$selfill && !$multi} {
  9133. set width [winfo width $path]
  9134. }
  9135. foreach item $data(selitems) {
  9136. set nitem [lindex $data(item,$item) 0]
  9137. set bbox [$path.c bbox $nitem]
  9138.  
  9139. if {[llength $bbox]} {
  9140. if {$selfill && !$multi} {
  9141. set bbox [list 0 [lindex $bbox 1] $width [lindex $bbox 3]]
  9142. }
  9143. set tags [list sel s:$item click]
  9144. set id [$path.c create rectangle $bbox  -fill $selbg -outline $selbg -tags $tags]
  9145. $path.c itemconfigure $nitem -fill $selfg
  9146. $path.c lower $id
  9147. $path.c lower b:$item
  9148. }
  9149. }
  9150. }
  9151.  
  9152.  
  9153. proc ListBox::_redraw_listbox { path } {
  9154. Widget::getVariable $path data
  9155.  
  9156. if {[Widget::getoption $path -redraw]} {
  9157. if {$data(upd,level) == 2} {
  9158. _redraw_items $path
  9159. }
  9160.  
  9161. _redraw_selection $path
  9162. _update_scrollregion $path
  9163.  
  9164. if {[Widget::cget $path -selectfill]} {
  9165. _update_select_fill $path
  9166. }
  9167.  
  9168. set data(upd,level)   0
  9169. set data(upd,afterid) ""
  9170. }
  9171. }
  9172.  
  9173.  
  9174. proc ListBox::_redraw_idle { path level } {
  9175. Widget::getVariable $path data
  9176.  
  9177. if {$data(nrows) != -1} {
  9178. if {[Widget::getoption $path -redraw] && $data(upd,afterid) == ""} {
  9179. set data(upd,afterid)  [after idle [list ListBox::_redraw_listbox $path]]
  9180. }
  9181. }
  9182. if {$level > $data(upd,level)} {
  9183. set data(upd,level) $level
  9184. }
  9185. }
  9186.  
  9187.  
  9188. proc ListBox::_resize { path } {
  9189. Widget::getVariable $path data
  9190.  
  9191. if {[Widget::getoption $path -multicolumn]} {
  9192. set bd    [$path.c cget -borderwidth]
  9193. set ht    [$path.c cget -highlightthickness]
  9194. set bd    [expr {$bd + $ht}]
  9195. set h     [expr {[winfo height $path] - 2*$bd}]
  9196. set nrows [expr {$h/[$path.c cget -yscrollincrement]}]
  9197. if {$nrows == 0} {
  9198. set nrows 1
  9199. }
  9200.  
  9201. if {$nrows != $data(nrows)} {
  9202. set data(nrows) $nrows
  9203. _redraw_idle $path 2
  9204. } else {
  9205. _update_scrollregion $path
  9206. }
  9207. } elseif {$data(nrows) == -1} {
  9208. set data(nrows) 0
  9209. ListBox::_redraw_listbox $path
  9210. if {[Widget::cget $path -selectfill]} {
  9211. _update_select_fill $path
  9212. }
  9213. } else {
  9214. if {[Widget::cget $path -selectfill]} {
  9215. _update_select_fill $path
  9216. }
  9217.  
  9218. _update_scrollregion $path
  9219. }
  9220. }
  9221.  
  9222.  
  9223. proc ListBox::_init_drag_cmd { path X Y top } {
  9224. set path [winfo parent $path]
  9225. set ltags [$path.c gettags current]
  9226. set item  [lindex $ltags 0]
  9227. if {[string equal $item "item"]
  9228. || [string equal $item "img"]
  9229. || [string equal $item "win"]} {
  9230. set item [string range [lindex $ltags 1] 2 end]
  9231. if {[llength [set cmd [Widget::getoption $path -draginitcmd]]]} {
  9232. return [uplevel \#0 $cmd [list $path $item $top]]
  9233. }
  9234. if { [set type [Widget::getoption $path -dragtype]] == "" } {
  9235. set type "LISTBOX_ITEM"
  9236. }
  9237. if { [set img [Widget::getoption $path.$item -image]] != "" } {
  9238. pack [label $top.l -image $img -padx 0 -pady 0]
  9239. }
  9240. return [list $type {copy move link} $item]
  9241. }
  9242. return {}
  9243. }
  9244.  
  9245.  
  9246. proc ListBox::_drop_cmd { path source X Y op type dnddata } {
  9247. set path [winfo parent $path]
  9248. Widget::getVariable $path data
  9249.  
  9250. if { [string length $data(dnd,afterid)] } {
  9251. after cancel $data(dnd,afterid)
  9252. set data(dnd,afterid) ""
  9253. }
  9254. $path.c delete drop
  9255. set data(dnd,scroll) ""
  9256. if { [llength $data(dnd,item)] || ![llength $data(items)] } {
  9257. if {[llength [set cmd [Widget::getoption $path -dropcmd]]]} {
  9258. return [uplevel \#0 $cmd [list $path $source $data(dnd,item) $op $type $dnddata]]
  9259. }
  9260. }
  9261. return 0
  9262. }
  9263.  
  9264.  
  9265. proc ListBox::_over_cmd { path source event X Y op type dnddata } {
  9266. set path [winfo parent $path]
  9267. Widget::getVariable $path data
  9268.  
  9269. if { [string equal $event "leave"] } {
  9270. $path.c delete drop
  9271. if { [string length $data(dnd,afterid)] } {
  9272. after cancel $data(dnd,afterid)
  9273. set data(dnd,afterid) ""
  9274. }
  9275. set data(dnd,scroll) ""
  9276. return 0
  9277. }
  9278.  
  9279. if { [string equal $event "enter"] } {
  9280. set mode [Widget::getoption $path -dropovermode]
  9281. set data(dnd,mode) 0
  9282. foreach c {w p i} {
  9283. set data(dnd,mode) [expr {($data(dnd,mode) << 1) | ([string first $c $mode] != -1)}]
  9284. }
  9285. }
  9286.  
  9287. set x [expr {$X-[winfo rootx $path]}]
  9288. set y [expr {$Y-[winfo rooty $path]}]
  9289. $path.c delete drop
  9290. set data(dnd,item) ""
  9291.  
  9292. if { $data(dnd,mode) != 4 && [_auto_scroll $path $x $y] != "" } {
  9293. return 2
  9294. }
  9295.  
  9296. if { $data(dnd,mode) & 4 } {
  9297. set target [list widget]
  9298. set vmode  4
  9299. } else {
  9300. set target [list ""]
  9301. set vmode  0
  9302. }
  9303. if { ($data(dnd,mode) & 2) && ![llength $data(items)] } {
  9304. lappend target "" 0
  9305. set vmode [expr {$vmode | 2}]
  9306. }
  9307.  
  9308. if { ($data(dnd,mode) & 3) && [llength $data(items)]} {
  9309. set len  [llength $data(items)]
  9310. set xc   [$path.c canvasx $x]
  9311. set yc   [$path.c canvasy $y]
  9312. set dy   [$path.c cget -yscrollincrement]
  9313. set line [expr {int($yc/$dy)}]
  9314. set yi   [expr {$line*$dy}]
  9315. set ys   [expr {$yi+$dy}]
  9316. set xi   0
  9317. set pos  $line
  9318. if { [Widget::getoption $path -multicolumn] } {
  9319. set nrows $data(nrows)
  9320. } else {
  9321. set nrows $len
  9322. }
  9323. if { $line < $nrows } {
  9324. foreach xs $data(xlist) {
  9325. if { $xc <= $xs } {
  9326. break
  9327. }
  9328. set  xi  $xs
  9329. incr pos $nrows
  9330. }
  9331. if { $pos < $len } {
  9332. set item [lindex $data(items) $pos]
  9333. set xi   [expr {[lindex [$path.c coords n:$item] 0]-[Widget::getoption $path -padx]-1}]
  9334. if { $data(dnd,mode) & 1 } {
  9335. lappend target $item
  9336. set vmode [expr {$vmode | 1}]
  9337. } else {
  9338. lappend target ""
  9339. }
  9340.  
  9341. if { $data(dnd,mode) & 2 } {
  9342. if { $yc >= $yi+$dy/2 } {
  9343. incr pos
  9344. set yl $ys
  9345. } else {
  9346. set yl $yi
  9347. }
  9348. lappend target $pos
  9349. set vmode [expr {$vmode | 2}]
  9350. } else {
  9351. lappend target ""
  9352. }
  9353. } else {
  9354. lappend target "" ""
  9355. }
  9356. } else {
  9357. lappend target "" ""
  9358. }
  9359.  
  9360. if { ($vmode & 3) == 3 } {
  9361. if { $yc-$yi <= 3 || $ys-$yc <= 3 } {
  9362. lappend target "position"
  9363. } else {
  9364. lappend target "item"
  9365. }
  9366. }
  9367. }
  9368.  
  9369. if {$vmode && [llength [set cmd [Widget::getoption $path -dropovercmd]]]} {
  9370. set res   [uplevel \#0 $cmd [list $source $target $op $type $dnddata]]
  9371. set code  [lindex $res 0]
  9372. set vmode 0
  9373. if {$code & 1} {
  9374. switch -exact -- [lindex $res 1] {
  9375. item     {set vmode 1}
  9376. position {set vmode 2}
  9377. widget   {set vmode 4}
  9378. }
  9379. }
  9380. } else {
  9381. if { ($vmode & 3) == 3 } {
  9382. if { [string equal [lindex $target 3] "position"] } {
  9383. set vmode [expr {$vmode & ~1}]
  9384. } else {
  9385. set vmode [expr {$vmode & ~2}]
  9386. }
  9387. }
  9388.  
  9389. if { $data(dnd,mode) == 4 || $data(dnd,mode) == 0 } {
  9390. set code 1
  9391. } else {
  9392. set code 3
  9393. }
  9394. }
  9395.  
  9396. if {[llength $data(items)]} {
  9397. if { $vmode & 1 } {
  9398. set data(dnd,item) [list "item" [lindex $target 1]]
  9399. if {[Widget::getoption $path -selectfill]} { incr xs -8 }
  9400. $path.c create rectangle $xi $yi $xs $ys -tags drop
  9401. } elseif { $vmode & 2 } {
  9402. set data(dnd,item) [concat "position" [lindex $target 2]]
  9403. $path.c create line $xi $yl $xs $yl -tags drop
  9404. } elseif { $vmode & 4 } {
  9405. set data(dnd,item) [list "widget"]
  9406. } else {
  9407. set code [expr {$code & 2}]
  9408. }
  9409. }
  9410.  
  9411. if { $code & 1 } {
  9412. DropSite::setcursor based_arrow_down
  9413. } else {
  9414. DropSite::setcursor dot
  9415. }
  9416. return $code
  9417. }
  9418.  
  9419.  
  9420. proc ListBox::_auto_scroll { path x y } {
  9421. Widget::getVariable $path data
  9422.  
  9423. set xmax   [winfo width  $path]
  9424. set ymax   [winfo height $path]
  9425. set scroll {}
  9426. if { $y <= 6 } {
  9427. if { [lindex [$path.c yview] 0] > 0 } {
  9428. set scroll [list yview -1]
  9429. DropSite::setcursor sb_up_arrow
  9430. }
  9431. } elseif { $y >= $ymax-6 } {
  9432. if { [lindex [$path.c yview] 1] < 1 } {
  9433. set scroll [list yview 1]
  9434. DropSite::setcursor sb_down_arrow
  9435. }
  9436. } elseif { $x <= 6 } {
  9437. if { [lindex [$path.c xview] 0] > 0 } {
  9438. set scroll [list xview -1]
  9439. DropSite::setcursor sb_left_arrow
  9440. }
  9441. } elseif { $x >= $xmax-6 } {
  9442. if { [lindex [$path.c xview] 1] < 1 } {
  9443. set scroll [list xview 1]
  9444. DropSite::setcursor sb_right_arrow
  9445. }
  9446. }
  9447.  
  9448. if { [string length $data(dnd,afterid)] && ![string equal $data(dnd,scroll) $scroll] } {
  9449. after cancel $data(dnd,afterid)
  9450. set data(dnd,afterid) ""
  9451. }
  9452.  
  9453. set data(dnd,scroll) $scroll
  9454. if { [llength $scroll] && ![string length $data(dnd,afterid)] } {
  9455. set data(dnd,afterid) [after 200 [list ListBox::_scroll $path $scroll]]
  9456. }
  9457. return $data(dnd,afterid)
  9458.  
  9459. }
  9460.  
  9461. proc ListBox::_multiple_select { path mode item } {
  9462. Widget::getVariable $path data
  9463.  
  9464. if {![info exists data(item,$data(anchor))]} { set data(anchor) $item }
  9465.  
  9466. if {[string equal [Widget::getoption $path -selectmode] "single"]} {
  9467. set mode none
  9468. }
  9469.  
  9470. switch -exact -- $mode {
  9471. "none" {
  9472. _mouse_select $path set $item
  9473. set data(anchor) $item
  9474. }
  9475.  
  9476. "control" {
  9477. _mouse_select $path toggle $item
  9478. set data(anchor) $item
  9479. }
  9480.  
  9481. "shift" {
  9482. _mouse_select $path range $data(anchor) $item
  9483. }
  9484. }
  9485. }
  9486.  
  9487.  
  9488. proc ListBox::_scroll { path cmd dir } {
  9489. Widget::getVariable $path data
  9490.  
  9491. if { ($dir == -1 && [lindex [$path.c $cmd] 0] > 0) ||
  9492. ($dir == 1  && [lindex [$path.c $cmd] 1] < 1) } {
  9493. $path $cmd scroll $dir units
  9494. set data(dnd,afterid)  [after 100 [list ListBox::_scroll $path $cmd $dir]]
  9495. } else {
  9496. set data(dnd,afterid) ""
  9497. DropSite::setcursor dot
  9498. }
  9499. }
  9500.  
  9501. proc ListBox::_set_help { path node } {
  9502. Widget::getVariable $path help
  9503.  
  9504. set item $path.$node
  9505. set opts [list -helptype -helptext -helpvar]
  9506. foreach {cty ctx cv} [eval [linsert $opts 0 Widget::hasChangedX $item]] break
  9507. set text [Widget::getoption $item -helptext]
  9508.  
  9509. if { (![info exists help($node)] && $text != "") || $cty || $ctx || $cv } {
  9510. set help($node) 1
  9511. set type [Widget::getoption $item -helptype]
  9512. switch $type {
  9513. balloon {
  9514. DynamicHelp::register $path.c balloon n:$node $text
  9515. DynamicHelp::register $path.c balloon i:$node $text
  9516. DynamicHelp::register $path.c balloon b:$node $text
  9517. }
  9518. variable {
  9519. set var [Widget::getoption $item -helpvar]
  9520. DynamicHelp::register $path.c variable n:$node $var $text
  9521. DynamicHelp::register $path.c variable i:$node $var $text
  9522. DynamicHelp::register $path.c variable b:$node $var $text
  9523. }
  9524. }
  9525. }
  9526. }
  9527.  
  9528. proc ListBox::_mouse_select { path cmd args } {
  9529. eval [linsert $args 0 selection $path $cmd]
  9530. switch -- $cmd {
  9531. "add" - "clear" - "remove" - "set" - "toggle" - "range" {
  9532. event generate $path <<ListboxSelect>>
  9533. }
  9534. }
  9535. }
  9536.  
  9537.  
  9538. proc ListBox::_get_current { path } {
  9539. set t [$path.c gettags current]
  9540. return [string range [lindex $t 1] 2 end]
  9541. }
  9542.  
  9543.  
  9544. proc ListBox::_drag_and_drop { path from endItem operation type startItem } {
  9545. if {[winfo parent $from] != $path} { return }
  9546.  
  9547. set place [lindex $endItem 0]
  9548. set i     [lindex $endItem 1]
  9549.  
  9550. switch -- $place {
  9551. "position" {
  9552. set idx $i
  9553. }
  9554.  
  9555. "item" {
  9556. set idx [$path index $i]
  9557. }
  9558.  
  9559. default {
  9560. return
  9561. }
  9562. }
  9563.  
  9564. if {$idx > [$path index $startItem]} { incr idx -1 }
  9565.  
  9566. if {[string equal $operation "copy"]} {
  9567. set options [Widget::options $path.$startItem]
  9568. eval [linsert $options 0 $path insert $idx $startItem\#auto]
  9569. } else {
  9570. $path move $startItem $idx
  9571. }
  9572. }
  9573.  
  9574.  
  9575. proc ListBox::_keyboard_navigation { path dir } {
  9576. Widget::getVariable $path data
  9577.  
  9578. set sel [$path index [lindex [$path selection get] end]]
  9579. if {$dir > 0} {
  9580. incr sel
  9581. if {$sel >= [llength $data(items)]} { return }
  9582. } else {
  9583. incr sel -1
  9584. if {$sel < 0} { return }
  9585. }
  9586. set item [lindex $data(items) $sel]
  9587. ListBox::see $path $item
  9588. _mouse_select $path set $item
  9589. }
  9590.  
  9591.  
  9592. namespace eval Separator {
  9593. Widget::define Separator separator
  9594.  
  9595. Widget::declare Separator {
  9596. {-background Color      "SystemButtonFace" 0}
  9597. {-cursor     String     ""         0}
  9598. {-relief     Enum       groove     0 {ridge groove}}
  9599. {-orient     Enum       horizontal 1 {horizontal vertical}}
  9600. {-bg         Synonym    -background}
  9601. }
  9602. Widget::addmap Separator "" :cmd { -background {} -cursor {} }
  9603.  
  9604. bind Separator <Destroy> [list Widget::destroy %W]
  9605. }
  9606.  
  9607.  
  9608. proc Separator::create { path args } {
  9609. Widget::initArgs Separator $args maps
  9610.  
  9611. eval [list frame $path -class Separator] $maps(:cmd)
  9612.  
  9613. Widget::initFromODB Separator $path $maps(Separator)
  9614.  
  9615. if {[string equal [Widget::cget $path -orient] "horizontal"]} {
  9616. $path configure -borderwidth 1 -height 2
  9617. } else {
  9618. $path configure -borderwidth 1 -width 2
  9619. }
  9620.  
  9621. if {[string equal [Widget::cget $path -relief] "groove"]} {
  9622. $path configure -relief sunken
  9623. } else {
  9624. $path configure -relief raised
  9625. }
  9626.  
  9627. return [Widget::create Separator $path]
  9628. }
  9629.  
  9630.  
  9631. proc Separator::configure { path args } {
  9632. set res [Widget::configure $path $args]
  9633.  
  9634. if { [Widget::hasChanged $path -relief relief] } {
  9635. if { $relief == "groove" } {
  9636. $path:cmd configure -relief sunken
  9637. } else {
  9638. $path:cmd configure -relief raised
  9639. }
  9640. }
  9641.  
  9642. return $res
  9643. }
  9644.  
  9645.  
  9646. proc Separator::cget { path option } {
  9647. return [Widget::cget $path $option]
  9648. }
  9649.  
  9650.  
  9651. namespace eval TTKButton {
  9652. Widget::define TTKButton button DynamicHelp
  9653.  
  9654. Widget::tkinclude TTKButton ttk::button :cmd  remove { -class }
  9655.  
  9656. Widget::declare TTKButton {
  9657. {-name                 String     ""      0 }
  9658. {-repeatdelay          Int        0       0 "%d >= 0" }
  9659. {-repeatinterval       Int        0       0 "%d >= 0" }
  9660. }
  9661.  
  9662. if 0 {
  9663. Widget::declare Button {
  9664. {-name                 String     ""      0 }
  9665. {-text                 String     ""      0 }
  9666. {-textvariable         String     ""      0 }
  9667. {-underline            Int        -1      0 "%d >= -1" }
  9668. {-armcommand           String     ""      0 }
  9669. {-disarmcommand        String     ""      0 }
  9670. {-command              String     ""      0 }
  9671. {-state                TkResource ""      0 button }
  9672. {-repeatdelay          Int        0       0 "%d >= 0" }
  9673. {-repeatinterval       Int        0       0 "%d >= 0" }
  9674. {-relief               Enum       raised  0
  9675. {raised sunken flat ridge solid groove link}}
  9676. {-image                String     ""      0 }
  9677. {-activeimage          String     ""      0 }
  9678. {-pressedimage         String     ""      0 }
  9679. {-disabledimage        String     ""      0 }
  9680. }
  9681.  
  9682. Widget::syncoptions Button "" :cmd { -text {} -underline {} }
  9683. }
  9684.  
  9685. DynamicHelp::include TTKButton balloon
  9686.  
  9687. variable _current ""
  9688. variable _pressed ""
  9689.  
  9690. }
  9691.  
  9692.  
  9693. proc TTKButton::create { path args } {
  9694. foreach {opt val} $args {
  9695. if {[Widget::optionExists TTKButton $opt]} {
  9696. lappend opts $opt $val
  9697. }
  9698. }
  9699.  
  9700. Widget::initArgs TTKButton $opts maps
  9701.  
  9702. eval [list ttk::button $path] $maps(:cmd)
  9703.  
  9704. Widget::initFromODB TTKButton $path $maps(TTKButton)
  9705.  
  9706. set var [$path cget -textvariable]
  9707. if {![string length $var]} {
  9708. set desc [BWidget::getname [Widget::getoption $path -name]]
  9709. if {[llength $desc]} {
  9710. set text  [lindex $desc 0]
  9711. set under [lindex $desc 1]
  9712. $path configure -text $text -underline $under
  9713. } else {
  9714. set text  [$path cget -text]
  9715. set under [$path cget -underline]
  9716. }
  9717. } else {
  9718. set text  ""
  9719. set under -1
  9720. $path configure -underline $under
  9721. }
  9722.  
  9723. set top [winfo toplevel $path]
  9724. bindtags $path [list $path TButton TTKButton $top all]
  9725.  
  9726. DynamicHelp::sethelp $path $path 1
  9727.  
  9728. return [Widget::create TTKButton $path]
  9729. }
  9730.  
  9731.  
  9732. proc TTKButton::configure { path args } {
  9733. set oldunder [$path:cmd cget -underline]
  9734. if {$oldunder != -1} {
  9735. set text      [$path:cmd cget -text]
  9736. set oldaccel1 [string tolower [string index $text $oldunder]]
  9737. set oldaccel2 [string toupper $oldaccel1]
  9738. } else {
  9739. set oldaccel1 ""
  9740. set oldaccel2 ""
  9741. }
  9742. set res [Widget::configure $path $args]
  9743.  
  9744. if {[Widget::anyChangedX $path -textvariable -name -text -underline]} {
  9745. set var   [Widget::cget $path -textvariable]
  9746. set text  [Widget::cget $path -text]
  9747. set under [Widget::cget $path -underline]
  9748.  
  9749. if {![string length $var]} {
  9750. set desc [BWidget::getname [Widget::cget $path -name]]
  9751. if {[llength $desc]} {
  9752. set text  [lindex $desc 0]
  9753. set under [lindex $desc 1]
  9754. }
  9755. } else {
  9756. set under -1
  9757. set text  ""
  9758. }
  9759. set top [winfo toplevel $path]
  9760. if {![string equal $oldaccel1 ""]} {
  9761. bind $top <Alt-$oldaccel1> {}
  9762. bind $top <Alt-$oldaccel2> {}
  9763. }
  9764. set accel1 [string tolower [string index $text $under]]
  9765. set accel2 [string toupper $accel1]
  9766. if {![string equal $accel1 ""]} {
  9767. bind $top <Alt-$accel1> [list TTKButton::invoke $path]
  9768. bind $top <Alt-$accel2> [list TTKButton::invoke $path]
  9769. }
  9770. $path:cmd configure -text $text -underline $under -textvariable $var
  9771. }
  9772.  
  9773. DynamicHelp::sethelp $path $path
  9774.  
  9775. return $res
  9776. }
  9777.  
  9778.  
  9779. proc TTKButton::cget { path option } {
  9780. Widget::cget $path $option
  9781. }
  9782.  
  9783.  
  9784. proc TTKButton::state { path args } {
  9785. return [uplevel #0 [list $path:cmd state] $args]
  9786. }
  9787.  
  9788.  
  9789. proc TTKButton::instate { path args } {
  9790. return [uplevel #0 [list $path:cmd instate] $args]
  9791. }
  9792.  
  9793.  
  9794. proc TTKButton::invoke { path } {
  9795. return [uplevel #0 [list $path:cmd invoke]]
  9796. }
  9797.  
  9798.  
  9799. proc TTKButton::_enter { path } {
  9800. variable _current
  9801. variable _pressed
  9802.  
  9803. set _current $path
  9804. if {![string equal [Widget::cget $path -state] "disabled"]} {
  9805. $path:cmd configure -state active
  9806. if {[string equal $_pressed $path]} {
  9807. $path:cmd configure -relief sunken
  9808. } elseif {[string equal [Widget::cget $path -relief] "link"]} {
  9809. $path:cmd configure -relief raised
  9810. }
  9811.  
  9812. set image [Widget::cget $path -activeimage]
  9813. if {[string equal $_pressed $path]} {
  9814. set pressedimage [Widget::cget $path -pressedimage]
  9815. if {![string equal $pressedimage ""]} { set image $pressedimage }
  9816. }
  9817. if {![string equal $image ""]} { $path:cmd configure -image $image }
  9818. }
  9819. }
  9820.  
  9821.  
  9822. proc TTKButton::_leave { path } {
  9823. variable _current
  9824. variable _pressed
  9825.  
  9826. set _current ""
  9827. if {[string equal [Widget::cget $path -state] "disabled"]} {
  9828. set dimg [Widget::cget $path -disabledimage]
  9829. if {![string equal $dimg ""]} { $path:cmd configure -state normal }
  9830. } else {
  9831. set relief [Widget::cget $path -relief]
  9832. if {[string equal $_pressed $path]} {
  9833. if {[string equal $relief "link"]} {
  9834. set relief raised
  9835. }
  9836. } elseif {[string equal $relief "link"]} {
  9837. set relief flat
  9838. }
  9839.  
  9840. $path:cmd configure  -relief $relief  -state  [Widget::cget $path -state]  -image  [Widget::cget $path -image]
  9841. }
  9842. }
  9843.  
  9844.  
  9845. proc TTKButton::_press { path } {
  9846. variable _pressed
  9847.  
  9848. if {![string equal [Widget::cget $path -state] "disabled"]} {
  9849. set _pressed $path
  9850. $path:cmd configure -relief sunken
  9851.  
  9852. set img [Widget::cget $path -pressedimage]
  9853. if {![string equal $img ""]} { $path:cmd configure -image $img }
  9854.  
  9855. set cmd [Widget::getoption $path -armcommand]
  9856. if {![string equal $cmd ""]} {
  9857. uplevel \#0 $cmd
  9858. set repeatdelay [Widget::getoption $path -repeatdelay]
  9859. set repeatint [Widget::getoption $path -repeatinterval]
  9860. if {$repeatdelay > 0} {
  9861. after $repeatdelay [list TTKButton::_repeat $path]
  9862. } elseif {$repeatint > 0} {
  9863. after $repeatint [list TTKButton::_repeat $path]
  9864. }
  9865. }
  9866. }
  9867. }
  9868.  
  9869.  
  9870. proc TTKButton::_release { path } {
  9871. variable _current
  9872. variable _pressed
  9873.  
  9874. if {[string equal $_pressed $path]} {
  9875. set pressed $_pressed
  9876. set _pressed ""
  9877. set relief [Widget::getoption $path -relief]
  9878. after cancel [list TTKButton::_repeat $path]
  9879.  
  9880. if {[string equal $relief "link"]} {
  9881. set relief raised
  9882. }
  9883.  
  9884. set image [Widget::cget $path -image]
  9885. if {[string equal $pressed $path]} {
  9886. set activeimage [Widget::cget $path -activeimage]
  9887. if {![string equal $activeimage ""]} { set image $activeimage }
  9888. }
  9889.  
  9890. $path:cmd configure -relief $relief -image $image
  9891.  
  9892. set cmd [Widget::getoption $path -disarmcommand]
  9893. if {![string equal $cmd ""]} {
  9894. uplevel \#0 $cmd
  9895. }
  9896.  
  9897. if {[string equal $_current $path] &&
  9898. ![string equal [Widget::cget $path -state] "disabled"] &&  [set cmd [Widget::getoption $path -command]] != ""} {
  9899. uplevel \#0 $cmd
  9900. }
  9901. }
  9902. }
  9903.  
  9904.  
  9905. proc TTKButton::_repeat { path } {
  9906. variable _current
  9907. variable _pressed
  9908.  
  9909. if {$_current == $path && $_pressed == $path &&
  9910. ![string equal [Widget::cget $path -state] "disabled"] &&
  9911. [set cmd [Widget::getoption $path -armcommand]] != ""} {
  9912. uplevel \#0 $cmd
  9913. }
  9914. if { $_pressed == $path &&
  9915. ([set delay [Widget::getoption $path -repeatinterval]] >0 ||
  9916. [set delay [Widget::getoption $path -repeatdelay]] > 0) } {
  9917. after $delay [list TTKButton::_repeat $path]
  9918. }
  9919. }
  9920.  
  9921.  
  9922. namespace eval Button {
  9923. if {[BWidget::using ttk]} {
  9924. Widget::define Button button TTKButton DynamicHelp
  9925. } else {
  9926. Widget::define Button button DynamicHelp
  9927. }
  9928.  
  9929. set remove [list -command -relief -text -textvariable  -underline -image -state]
  9930. if {[info tclversion] > 8.3} {
  9931. lappend remove -repeatdelay -repeatinterval
  9932. }
  9933.  
  9934. Widget::tkinclude Button button :cmd remove $remove
  9935.  
  9936. Widget::declare Button {
  9937. {-name                 String     ""      0 }
  9938. {-text                 String     ""      0 }
  9939. {-textvariable         String     ""      0 }
  9940. {-underline            Int        -1      0 "%d >= -1" }
  9941. {-armcommand           String     ""      0 }
  9942. {-disarmcommand        String     ""      0 }
  9943. {-command              String     ""      0 }
  9944. {-state                TkResource ""      0 button }
  9945. {-repeatdelay          Int        0       0 "%d >= 0" }
  9946. {-repeatinterval       Int        0       0 "%d >= 0" }
  9947. {-relief               Enum       raised  0
  9948. {raised sunken flat ridge solid groove link}}
  9949. {-image                String     ""      0 }
  9950. {-activeimage          String     ""      0 }
  9951. {-pressedimage         String     ""      0 }
  9952. {-disabledimage        String     ""      0 }
  9953. }
  9954.  
  9955. Widget::addmap Button "" :cmd { -text {} -underline {} }
  9956.  
  9957. DynamicHelp::include Button balloon
  9958.  
  9959. variable _current ""
  9960. variable _pressed ""
  9961.  
  9962. bind BwButton <Enter>           {Button::_enter %W}
  9963. bind BwButton <Leave>           {Button::_leave %W}
  9964. bind BwButton <ButtonPress-1>   {Button::_press %W}
  9965. bind BwButton <ButtonRelease-1> {Button::_release %W}
  9966. bind BwButton <Key-space>       {Button::invoke %W; break}
  9967. bind BwButton <Return>          {Button::invoke %W; break}
  9968. bind BwButton <Destroy>         {Widget::destroy %W}
  9969. }
  9970.  
  9971.  
  9972. proc Button::create { path args } {
  9973. if {[BWidget::using ttk]} {
  9974. return [eval [list TTKButton::create $path] $args]
  9975. }
  9976.  
  9977. Widget::initArgs Button $args maps
  9978.  
  9979. eval [list button $path] $maps(:cmd)
  9980.  
  9981. Widget::initFromODB Button $path $maps(Button)
  9982.  
  9983. set var [$path cget -textvariable]
  9984. if {![string length $var]} {
  9985. set desc [BWidget::getname [Widget::getoption $path -name]]
  9986. if {[llength $desc]} {
  9987. set text  [lindex $desc 0]
  9988. set under [lindex $desc 1]
  9989. $path configure -text $text -underline $under
  9990. } else {
  9991. set text  [$path cget -text]
  9992. set under [$path cget -underline]
  9993. }
  9994. } else {
  9995. set text  ""
  9996. set under -1
  9997. $path configure -underline $under
  9998. }
  9999.  
  10000. set relief [Widget::getoption $path -relief]
  10001. if {[string equal $relief "link"]} { set relief flat }
  10002.  
  10003. set opts [list]
  10004. lappend opts -text $text -underline $under -textvariable $var
  10005. lappend opts -relief $relief -state [Widget::cget $path -state]
  10006. lappend opts -image [Widget::cget $path -image]
  10007.  
  10008. eval [list $path configure] $opts
  10009.  
  10010. set top [winfo toplevel $path]
  10011. bindtags $path [list $path BwButton $top all]
  10012.  
  10013. set accel1 [string tolower [string index $text $under]]
  10014. set accel2 [string toupper $accel1]
  10015. if {[string length $accel1]} {
  10016. bind $top <Alt-$accel1> [list Button::invoke $path]
  10017. bind $top <Alt-$accel2> [list Button::invoke $path]
  10018. }
  10019.  
  10020. DynamicHelp::sethelp $path $path 1
  10021.  
  10022. return [Widget::create Button $path]
  10023. }
  10024.  
  10025.  
  10026. proc Button::configure { path args } {
  10027. set oldunder [$path:cmd cget -underline]
  10028. if {$oldunder != -1} {
  10029. set text      [$path:cmd cget -text]
  10030. set oldaccel1 [string tolower [string index $text $oldunder]]
  10031. set oldaccel2 [string toupper $oldaccel1]
  10032. } else {
  10033. set oldaccel1 ""
  10034. set oldaccel2 ""
  10035. }
  10036. set res [Widget::configure $path $args]
  10037.  
  10038. if {[Widget::anyChangedX $path -relief -state]} {
  10039. set state  [Widget::cget $path -state]
  10040. set relief [Widget::cget $path -relief]
  10041. if {[string equal $relief "link"]} {
  10042. if {[string equal $state "active"]} {
  10043. set relief "raised"
  10044. } else {
  10045. set relief "flat"
  10046. }
  10047. }
  10048.  
  10049. $path:cmd configure -relief $relief
  10050.  
  10051. set dimg [Widget::cget $path -disabledimage]
  10052. if {[string equal $state "disabled"] && ![string equal $dimg ""]} {
  10053. $path:cmd configure -image $dimg
  10054. } else {
  10055. $path:cmd configure  -state      $state  -image      [Widget::cget $path -image]  -background [Widget::cget $path -background]  -foreground [Widget::cget $path -foreground]
  10056. }
  10057. }
  10058.  
  10059. if {[Widget::hasChanged $path -image image]} {
  10060. $path:cmd configure -image $image
  10061. }
  10062.  
  10063. if {[Widget::anyChangedX $path -textvariable -name -text -underline]} {
  10064. set var   [Widget::cget $path -textvariable]
  10065. set text  [Widget::cget $path -text]
  10066. set under [Widget::cget $path -underline]
  10067.  
  10068. if {![string length $var]} {
  10069. set desc [BWidget::getname [Widget::cget $path -name]]
  10070. if {[llength $desc]} {
  10071. set text  [lindex $desc 0]
  10072. set under [lindex $desc 1]
  10073. }
  10074. } else {
  10075. set under -1
  10076. set text  ""
  10077. }
  10078. set top [winfo toplevel $path]
  10079. if {![string equal $oldaccel1 ""]} {
  10080. bind $top <Alt-$oldaccel1> {}
  10081. bind $top <Alt-$oldaccel2> {}
  10082. }
  10083. set accel1 [string tolower [string index $text $under]]
  10084. set accel2 [string toupper $accel1]
  10085. if {![string equal $accel1 ""]} {
  10086. bind $top <Alt-$accel1> [list Button::invoke $path]
  10087. bind $top <Alt-$accel2> [list Button::invoke $path]
  10088. }
  10089. $path:cmd configure -text $text -underline $under -textvariable $var
  10090. }
  10091.  
  10092. DynamicHelp::sethelp $path $path
  10093.  
  10094. return $res
  10095. }
  10096.  
  10097.  
  10098. proc Button::cget { path option } {
  10099. Widget::cget $path $option
  10100. }
  10101.  
  10102.  
  10103. proc Button::invoke { path } {
  10104. if {[string equal [Widget::cget $path -state] "disabled"]} { return }
  10105.  
  10106. $path:cmd configure -state active -relief sunken
  10107. update idletasks
  10108.  
  10109. set cmd [Widget::getoption $path -armcommand]
  10110. if {![string equal $cmd ""]} {
  10111. uplevel \#0 $cmd
  10112. }
  10113. after 100
  10114. set relief [Widget::getoption $path -relief]
  10115. if {[string equal $relief "link"]} {
  10116. set relief flat
  10117. }
  10118. $path:cmd configure  -state  [Widget::getoption $path -state]  -relief $relief
  10119. set cmd [Widget::getoption $path -disarmcommand]
  10120. if {![string equal $cmd ""]} {
  10121. uplevel \#0 $cmd
  10122. }
  10123. set cmd [Widget::getoption $path -command]
  10124. if {![string equal $cmd ""]} {
  10125. uplevel \#0 $cmd
  10126. }
  10127. }
  10128.  
  10129.  
  10130. proc Button::_enter { path } {
  10131. variable _current
  10132. variable _pressed
  10133.  
  10134. set _current $path
  10135. if {![string equal [Widget::cget $path -state] "disabled"]} {
  10136. $path:cmd configure -state active
  10137. if {[string equal $_pressed $path]} {
  10138. $path:cmd configure -relief sunken
  10139. } elseif {[string equal [Widget::cget $path -relief] "link"]} {
  10140. $path:cmd configure -relief raised
  10141. }
  10142.  
  10143. set image [Widget::cget $path -activeimage]
  10144. if {[string equal $_pressed $path]} {
  10145. set pressedimage [Widget::cget $path -pressedimage]
  10146. if {![string equal $pressedimage ""]} { set image $pressedimage }
  10147. }
  10148. if {![string equal $image ""]} { $path:cmd configure -image $image }
  10149. }
  10150. }
  10151.  
  10152.  
  10153. proc Button::_leave { path } {
  10154. variable _current
  10155. variable _pressed
  10156.  
  10157. set _current ""
  10158. if {[string equal [Widget::cget $path -state] "disabled"]} {
  10159. set dimg [Widget::cget $path -disabledimage]
  10160. if {![string equal $dimg ""]} { $path:cmd configure -state normal }
  10161. } else {
  10162. set relief [Widget::cget $path -relief]
  10163. if {[string equal $_pressed $path]} {
  10164. if {[string equal $relief "link"]} {
  10165. set relief raised
  10166. }
  10167. } elseif {[string equal $relief "link"]} {
  10168. set relief flat
  10169. }
  10170.  
  10171. $path:cmd configure  -relief $relief  -state  [Widget::cget $path -state]  -image  [Widget::cget $path -image]
  10172. }
  10173. }
  10174.  
  10175.  
  10176. proc Button::_press { path } {
  10177. variable _pressed
  10178.  
  10179. if {![string equal [Widget::cget $path -state] "disabled"]} {
  10180. set _pressed $path
  10181. $path:cmd configure -relief sunken
  10182.  
  10183. set img [Widget::cget $path -pressedimage]
  10184. if {![string equal $img ""]} { $path:cmd configure -image $img }
  10185.  
  10186. set cmd [Widget::getoption $path -armcommand]
  10187. if {![string equal $cmd ""]} {
  10188. uplevel \#0 $cmd
  10189. set repeatdelay [Widget::getoption $path -repeatdelay]
  10190. set repeatint [Widget::getoption $path -repeatinterval]
  10191. if {$repeatdelay > 0} {
  10192. after $repeatdelay "Button::_repeat $path"
  10193. } elseif {$repeatint > 0} {
  10194. after $repeatint "Button::_repeat $path"
  10195. }
  10196. }
  10197. }
  10198. }
  10199.  
  10200.  
  10201. proc Button::_release { path } {
  10202. variable _current
  10203. variable _pressed
  10204.  
  10205. if {[string equal $_pressed $path]} {
  10206. set pressed $_pressed
  10207. set _pressed ""
  10208. set relief [Widget::getoption $path -relief]
  10209. after cancel "Button::_repeat $path"
  10210.  
  10211. if {[string equal $relief "link"]} {
  10212. set relief raised
  10213. }
  10214.  
  10215. set image [Widget::cget $path -image]
  10216. if {[string equal $pressed $path]} {
  10217. set activeimage [Widget::cget $path -activeimage]
  10218. if {![string equal $activeimage ""]} { set image $activeimage }
  10219. }
  10220.  
  10221. $path:cmd configure -relief $relief -image $image
  10222.  
  10223. set cmd [Widget::getoption $path -disarmcommand]
  10224. if {![string equal $cmd ""]} {
  10225. uplevel \#0 $cmd
  10226. }
  10227.  
  10228. if {[string equal $_current $path] &&
  10229. ![string equal [Widget::cget $path -state] "disabled"] &&  [set cmd [Widget::getoption $path -command]] != ""} {
  10230. uplevel \#0 $cmd
  10231. }
  10232. }
  10233. }
  10234.  
  10235.  
  10236. proc Button::_repeat { path } {
  10237. variable _current
  10238. variable _pressed
  10239.  
  10240. if {$_current == $path && $_pressed == $path &&
  10241. ![string equal [Widget::cget $path -state] "disabled"] &&
  10242. [set cmd [Widget::getoption $path -armcommand]] != ""} {
  10243. uplevel \#0 $cmd
  10244. }
  10245. if { $_pressed == $path &&
  10246. ([set delay [Widget::getoption $path -repeatinterval]] >0 ||
  10247. [set delay [Widget::getoption $path -repeatdelay]] > 0) } {
  10248. after $delay "Button::_repeat $path"
  10249. }
  10250. }
  10251.  
  10252.  
  10253. namespace eval ButtonBox {
  10254. Widget::define ButtonBox buttonbox Button
  10255.  
  10256. namespace eval Button {
  10257. Widget::declare ButtonBox::Button {
  10258. {-tags              String    ""            0}
  10259. {-hide              Boolean   0             0}
  10260. {-value             String    ""            0}
  10261. {-spacing           Int       -1            0 "%d >= -1"}
  10262. }
  10263. }
  10264.  
  10265. if {[BWidget::using ttk]} {
  10266. Widget::tkinclude ButtonBox ttk::frame :cmd  remove { -class -colormap -container -padx -pady -visual }
  10267. } else {
  10268. Widget::tkinclude ButtonBox frame :cmd  remove { -class -colormap -container -padx -pady -visual }
  10269. }
  10270.  
  10271. Widget::declare ButtonBox {
  10272. {-orient      Enum       horizontal 0 {horizontal vertical}}
  10273. {-state       Enum       "normal"   0 {disabled normal}}
  10274. {-homogeneous Boolean    1          0}
  10275. {-spacing     Int        10         0 "%d >= 0"}
  10276. {-padx        Int        1          0}
  10277. {-pady        Int        1          0}
  10278. {-default     String     -1         0}
  10279. {-rows        Int        "0"        0}
  10280. {-columns     Int        "0"        0}
  10281. }
  10282.  
  10283. bind ButtonBox <Map>     [list ButtonBox::_realize %W]
  10284. bind ButtonBox <Destroy> [list ButtonBox::_destroy %W]
  10285. }
  10286.  
  10287.  
  10288. proc ButtonBox::create { path args } {
  10289. Widget::initArgs ButtonBox $args maps
  10290.  
  10291. if {[BWidget::using ttk]} {
  10292. eval [list ttk::frame $path -class ButtonBox] $maps(:cmd)
  10293. } else {
  10294. eval [list frame $path -class ButtonBox] $maps(:cmd)
  10295. }
  10296.  
  10297. Widget::initFromODB ButtonBox $path $maps(ButtonBox)
  10298.  
  10299. if {![BWidget::using ttk]
  10300. && [info tclversion] >= 8.4} { $path configure -padx 0 -pady 0 }
  10301.  
  10302. Widget::getVariable $path data
  10303.  
  10304. set data(max)      0
  10305. set data(nbuttons) 0
  10306. set data(realized) 0
  10307. set data(buttons)  [list]
  10308. set data(widgets)  [list]
  10309. set data(default)  [Widget::getoption $path -default]
  10310.  
  10311. return [Widget::create ButtonBox $path]
  10312. }
  10313.  
  10314.  
  10315. proc ButtonBox::configure { path args } {
  10316. Widget::getVariable $path data
  10317.  
  10318. set res [Widget::configure $path $args]
  10319.  
  10320. if {[Widget::hasChanged $path -default val]} {
  10321. _select_default $path
  10322. }
  10323.  
  10324. if {[Widget::hasChanged $path -state val]} {
  10325. foreach i $data(buttons) {
  10326. $path.b$i configure -state $val
  10327. }
  10328. }
  10329.  
  10330. set opts [list -rows -columns -orient -homogeneous]
  10331. if {[eval [list Widget::anyChangedX $path] $opts]} { _redraw $path }
  10332.  
  10333. return $res
  10334. }
  10335.  
  10336.  
  10337. proc ButtonBox::cget { path option } {
  10338. return [Widget::cget $path $option]
  10339. }
  10340.  
  10341.  
  10342. proc ButtonBox::add { path args } {
  10343. return [eval insert $path end $args]
  10344. }
  10345.  
  10346.  
  10347. proc ButtonBox::insert { path idx args } {
  10348. Widget::getVariable $path data
  10349. Widget::getVariable $path tags
  10350.  
  10351. set but $path.b$data(nbuttons)
  10352.  
  10353. set class Button
  10354. if {[BWidget::using ttk]} { set class TTKButton }
  10355. array set maps [Widget::splitArgs $args $class ButtonBox::Button]
  10356.  
  10357. Widget::init ButtonBox::Button $but#bbox $maps(ButtonBox::Button)
  10358.  
  10359. set spacing [Widget::getOption -spacing -1 $but#bbox $path]
  10360.  
  10361. if {[string equal $idx "end"] && $data(nbuttons)} {
  10362. set data(spacing,$data(nbuttons)) [list left $spacing]
  10363. lappend data(widgets) $but
  10364. lappend data(buttons) $data(nbuttons)
  10365. } else {
  10366. set data(spacing,$data(nbuttons)) [list right $spacing]
  10367. set data(widgets) [linsert $data(widgets) $idx $but]
  10368. set data(buttons) [linsert $data(buttons) $idx $data(nbuttons)]
  10369. }
  10370.  
  10371. set opts [list]
  10372. if {![BWidget::using ttk]} {
  10373. lappend opts -padx [Widget::getoption $path -padx]
  10374. lappend opts -pady [Widget::getoption $path -pady]
  10375. }
  10376.  
  10377. eval [list Button::create $but] $opts $maps(:cmd) $maps($class)
  10378.  
  10379. foreach tag [Widget::getoption $but#bbox -tags] {
  10380. lappend tags($tag) $but
  10381. if {![info exists tags($tag,state)]} { set tags($tag,state) 1 }
  10382. }
  10383.  
  10384. _redraw_idle $path
  10385.  
  10386. _select_default $path
  10387.  
  10388. incr data(nbuttons)
  10389.  
  10390. return $but
  10391. }
  10392.  
  10393.  
  10394. proc ButtonBox::delete { path index } {
  10395. Widget::getVariable $path data
  10396. Widget::getVariable $path tags
  10397.  
  10398. set button $path.b$i
  10399. set widget $button#bbox
  10400.  
  10401. set i [lindex $data(buttons) $index]
  10402. set data(buttons) [lreplace $data(buttons) $index $index]
  10403. set data(widgets) [lreplace $data(widgets) $index $index]
  10404.  
  10405. foreach tag [Widget::getoption $widget -tags] {
  10406. set tags($tag) [BWidget::lremove $tags($tag) $button]
  10407. if {![llength $tags($tag)]} {
  10408. unset tags($tag) tags($tag,state)
  10409. }
  10410. }
  10411.  
  10412. Widget::destroy $widget 0
  10413.  
  10414. destroy $button
  10415.  
  10416. _redraw_idle $path
  10417. }
  10418.  
  10419.  
  10420. proc ButtonBox::buttons { path {first ""} {last ""} } {
  10421. Widget::getVariable $path data
  10422. if {![string length $first]} { return $data(widgets) }
  10423. if {![string length $last]}  { return [lindex $data(widgets) $first] }
  10424. return [lrange $data(widgets) $first $last]
  10425. }
  10426.  
  10427.  
  10428. proc ButtonBox::itemconfigure { path index args } {
  10429. Widget::getVariable $path data
  10430.  
  10431. set idx    [index $path $index]
  10432. set button $path.b$idx
  10433.  
  10434. set class Button
  10435. if {[BWidget::using ttk]} { set class TTKButton }
  10436.  
  10437. if {![llength $args]} {
  10438. set res [${class}::configure $button]
  10439. eval lappend res [Widget::configure $button#bbox [list]]
  10440. return [lsort $res]
  10441. }
  10442.  
  10443. if {[llength $args] == 1} {
  10444. if {[Widget::optionExists Button $args]} {
  10445. return [${class}::configure $button $args]
  10446. } else {
  10447. return [Widget::configure $button#bbox $args]
  10448. }
  10449. }
  10450.  
  10451. array set maps [Widget::splitArgs $args $class ButtonBox::Button]
  10452.  
  10453. if {[info exists maps(ButtonBox::Button)]} {
  10454. set oldtags [Widget::getoption $button#bbox -tags]
  10455.  
  10456. Widget::configure $button#bbox $maps(ButtonBox::Button)
  10457.  
  10458. if {[Widget::hasChanged $button#bbox -tags newtags]} {
  10459. Widget::getVariable $path tags
  10460.  
  10461. foreach tag $oldtags {
  10462. set tags($tag) [BWidget::lremove $tags($tag) $button]
  10463. if {![llength $tags($tag)]} {
  10464. unset tags($tag) tags($tag,state)
  10465. }
  10466. }
  10467.  
  10468. foreach tag $newtags {
  10469. lappend tags($tag) $button
  10470. if {![info exists tags($tag,state)]} { set tags($tag,state) 1 }
  10471. }
  10472. }
  10473.  
  10474. set redraw 0
  10475.  
  10476. if {[Widget::hasChanged $button#bbox -spacing spacing]} {
  10477. set redraw 1
  10478. set data(spacing,$idx) [lreplace $data(spacing,$idx) 1 1 $spacing]
  10479. }
  10480.  
  10481. if {[Widget::hasChanged $button#bbox -hide hide]} {
  10482. set redraw 1
  10483. }
  10484.  
  10485. if {$redraw} { _redraw_idle $path }
  10486. }
  10487.  
  10488. if {[llength $maps(:cmd)] || [llength $maps($class)]} {
  10489. eval [list ${class}::configure $button] $maps(:cmd) $maps($class)
  10490. }
  10491. }
  10492.  
  10493.  
  10494. proc ButtonBox::itemcget { path index option } {
  10495. set button $path.b[index $path $index]
  10496. if {[Widget::optionExists Button $option]} {
  10497. return [Button::cget $button $option]
  10498. } else {
  10499. return [Widget::cget $button#bbox $option]
  10500. }
  10501. }
  10502.  
  10503.  
  10504. proc ButtonBox::setfocus { path index } {
  10505. set but $path.b[index $path $index]
  10506. if {[winfo exists $but]} { focus $but }
  10507. }
  10508.  
  10509.  
  10510. proc ButtonBox::invoke { path index } {
  10511. set but $path.b[index $path $index]
  10512. if {[winfo exists $but]} { $but invoke }
  10513. }
  10514.  
  10515.  
  10516. proc ButtonBox::index { path index } {
  10517. Widget::getVariable $path data
  10518.  
  10519. set n [expr {$data(nbuttons) - 1}]
  10520.  
  10521. if {[string is integer -strict $index]} {
  10522. set res $index
  10523. if {$index > $n} { set res $n }
  10524. return $res
  10525. }
  10526.  
  10527. if {[string equal $index "default"]} {
  10528. set res [Widget::getoption $path -default]
  10529. } elseif {[string equal $index "end"] || [string equal $index "last"]} {
  10530. set res $n
  10531. } elseif {[set res [lsearch -exact $data(widgets) $index]] > -1} {
  10532. } else {
  10533. foreach i $data(buttons) {
  10534. set w $path.b$i
  10535. lappend text  [$w cget -text]
  10536. lappend names [$w cget -name]
  10537. }
  10538. set len [llength $data(buttons)]
  10539. set res [lsearch -exact [concat $names $text] $index]
  10540. if {$res >= $len} { set res [expr {$res - $len}] }
  10541. }
  10542. return $res
  10543. }
  10544.  
  10545.  
  10546.  
  10547. proc ButtonBox::gettags { path } {
  10548. Widget::getVariable $path tags
  10549.  
  10550. set tags [list]
  10551.  
  10552. foreach tag [array names tags] {
  10553. if {![string match "*,state" $tag]} { lappend tags $tag }
  10554. }
  10555. return $tags
  10556. }
  10557.  
  10558.  
  10559.  
  10560. proc ButtonBox::setbuttonstate { path tag state } {
  10561. Widget::getVariable $path tags
  10562.  
  10563. if {![info exists tags($tag)]} { return }
  10564.  
  10565. set tags($tag,state) $state
  10566. foreach button $tags($tag) {
  10567. set expression 1
  10568. foreach buttontag [Widget::getoption $button#bbox -tags] {
  10569. lappend expression && $tags($buttontag,state)
  10570. }
  10571.  
  10572. if {[expr $expression]} {
  10573. set state normal
  10574. } else {
  10575. set state disabled
  10576. }
  10577.  
  10578. $button configure -state $state
  10579. }
  10580. }
  10581.  
  10582.  
  10583. proc ButtonBox::getbuttonstate { path tag } {
  10584. Widget::getVariable $path tags
  10585.  
  10586. if {![info exists tags($tag)]} {
  10587. return -code error "unknown tag \"$tag\""
  10588. }
  10589.  
  10590. return $tags($tag,state)
  10591. }
  10592.  
  10593.  
  10594. proc ButtonBox::_select_default { path } {
  10595. Widget::getVariable $path data
  10596.  
  10597. set default [Widget::getoption $path -default]
  10598. set data(default) [ButtonBox::index $path $default]
  10599.  
  10600. foreach i $data(buttons) {
  10601. set button $path.b$i
  10602. if {$i == $data(default)} {
  10603. if {[BWidget::using ttk]} {
  10604. $button state focus
  10605. } else {
  10606. $button configure -default active
  10607. }
  10608. } else {
  10609. if {[BWidget::using ttk]} {
  10610. $button state !focus
  10611. } else {
  10612. $button configure -default normal
  10613. }
  10614. }
  10615. incr i
  10616. }
  10617. }
  10618.  
  10619.  
  10620. proc ButtonBox::_redraw_idle { path } {
  10621. Widget::getVariable $path data
  10622.  
  10623. if {![info exists data(redraw)]} {
  10624. set data(redraw) 1
  10625. after idle [list ButtonBox::_redraw $path]
  10626. }
  10627. }
  10628.  
  10629.  
  10630. proc ButtonBox::_redraw { path } {
  10631. Widget::getVariable $path data
  10632. Widget::getVariable $path buttons
  10633.  
  10634. set data(redraw) 1
  10635.  
  10636.  
  10637. set rows [Widget::getoption $path -rows]
  10638. set cols [Widget::getoption $path -columns]
  10639.  
  10640. set idx     0
  10641. set rowidx  0
  10642. set colidx  0
  10643. set idxs [list]
  10644. foreach i $data(buttons) {
  10645. set dir     [lindex $data(spacing,$i) 0]
  10646. set spacing [lindex $data(spacing,$i) 1]
  10647. set but $path.b$i
  10648. if {[string equal [Widget::getoption $path -orient] "horizontal"]} {
  10649. if {![Widget::getoption $but#bbox -hide]} {
  10650. grid $but -column $idx -row $rowidx -sticky nsew
  10651. } else {
  10652. grid remove $but
  10653. }
  10654.  
  10655. if {[Widget::getoption $path -homogeneous]} {
  10656. set req [winfo reqwidth $but]
  10657. if { $req > $data(max) } {
  10658. grid columnconfigure $path [expr {2*$i}] -minsize $req
  10659. set data(max) $req
  10660. }
  10661. grid columnconfigure $path $idx -minsize $data(max) -weight 1
  10662. } else {
  10663. grid columnconfigure $path $idx -weight 0
  10664. }
  10665.  
  10666. set col [expr {$idx - 1}]
  10667. if {[string equal $dir "right"]} { set col [expr {$idx + 1}] }
  10668. if {$col > 0 && [lsearch -exact $idxs $col] < 0} {
  10669. lappend idxs $col
  10670. grid columnconfigure $path $col -minsize $spacing
  10671. }
  10672.  
  10673. incr colidx
  10674.  
  10675. if {$cols > 0 && $colidx >= $cols} {
  10676. set idx -2
  10677. incr rowidx
  10678. set colidx 0
  10679. }
  10680. } else {
  10681. if {![Widget::getoption $but#bbox -hide]} {
  10682. grid $but -column $colidx -row $idx -sticky nsew
  10683. } else {
  10684. grid remove $but
  10685. }
  10686.  
  10687. grid rowconfigure $path $idx -weight 0
  10688.  
  10689. set row [expr {$idx - 1}]
  10690. if {[string equal $dir "right"]} { set row [expr {$idx + 1}] }
  10691. if {$row > 0 && [lsearch -exact $idxs $row] < 0} {
  10692. lappend idxs $row
  10693. grid rowconfigure $path $row -minsize $spacing
  10694. }
  10695.  
  10696. incr rowidx
  10697.  
  10698. if {$rows > 0 && $rowidx >= $rows} {
  10699. set idx -2
  10700. incr colidx
  10701. set rowidx 0
  10702. }
  10703. }
  10704. incr idx 2
  10705. }
  10706.  
  10707. unset data(redraw)
  10708. }
  10709.  
  10710.  
  10711. proc ButtonBox::_realize { path } {
  10712. Widget::getVariable $path data
  10713.  
  10714. if {!$data(realized)} {
  10715. set data(realized) 1
  10716. ButtonBox::_redraw $path
  10717. }
  10718. }
  10719.  
  10720.  
  10721. proc ButtonBox::_destroy { path } {
  10722. Widget::getVariable $path data
  10723.  
  10724. foreach i $data(buttons) {
  10725. set button $path.b$i
  10726. Widget::destroy $button#bbox 0
  10727. }
  10728.  
  10729. Widget::destroy $path
  10730. }
  10731.  
  10732.  
  10733. namespace eval Dialog {
  10734. Widget::define Dialog dialog ButtonBox
  10735.  
  10736. Widget::bwinclude Dialog ButtonBox .bbox  remove {
  10737. -orient -background
  10738. } initialize {
  10739. -spacing 10 -padx 10
  10740. }
  10741.  
  10742. Widget::declare Dialog {
  10743. {-background    Color    "SystemButtonFace" 0}
  10744. {-title         String   ""      0}
  10745. {-geometry      String   ""      0}
  10746. {-modal         Enum     local   0 {none local global}}
  10747. {-bitmap        String   ""      1}
  10748. {-image         String   ""      1}
  10749. {-separator     Boolean  0       1}
  10750. {-cancel        Int      -1      0 "%d >= -1"}
  10751. {-parent        String   ""      0}
  10752. {-side          Enum     bottom  1 {bottom left top right}}
  10753. {-anchor        Enum     c       1 {n e w s c}}
  10754. {-class         String   Dialog  1}
  10755. {-transient     Boolean  1       1}
  10756. {-place         Enum     center  1 {none center left right above below}}
  10757. {-placerelative Boolean  1       1}
  10758.  
  10759. {-bg            Synonym  -background}
  10760. }
  10761.  
  10762. if {![BWidget::using ttk]} {
  10763. Widget::addmap Dialog "" :cmd   {-background {}}
  10764. Widget::addmap Dialog "" .frame {-background {}}
  10765. }
  10766.  
  10767. bind Dialog <Destroy> [list Dialog::_destroy %W]
  10768. }
  10769.  
  10770.  
  10771. proc Dialog::create { path args } {
  10772. Widget::initArgs Dialog $args maps
  10773.  
  10774. array set _args $maps(Dialog)
  10775. set class "Dialog"
  10776. if {[info exists _args(-class)]} { set class $_args(-class) }
  10777.  
  10778. if {[string equal $::tcl_platform(platform) "unix"]} {
  10779. set re raised
  10780. set bd 1
  10781. } else {
  10782. set re flat
  10783. set bd 0
  10784. }
  10785. toplevel $path -relief $re -borderwidth $bd -class $class  -background $::BWidget::colors(SystemButtonFace)
  10786. wm protocol $path WM_DELETE_WINDOW [list Dialog::enddialog $path -1 1]
  10787.  
  10788. Widget::initFromODB Dialog $path $maps(Dialog)
  10789.  
  10790. bindtags $path [list $path $class all]
  10791. wm overrideredirect $path 1
  10792. wm title $path [Widget::cget $path -title]
  10793.  
  10794. set parent [Widget::cget $path -parent]
  10795. if {![winfo exists $parent]} {
  10796. set parent [winfo parent $path]
  10797. }
  10798.  
  10799. if {[Widget::getoption $path -transient]} {
  10800. wm transient $path [winfo toplevel $parent]
  10801. }
  10802. wm withdraw $path
  10803.  
  10804. set side [Widget::cget $path -side]
  10805. if {[string equal $side "left"] || [string equal $side "right"]} {
  10806. set orient vertical
  10807. } else {
  10808. set orient horizontal
  10809. }
  10810.  
  10811. eval [list ButtonBox::create $path.bbox] $maps(.bbox) -orient $orient
  10812. set frame [frame $path.frame -relief flat -borderwidth 0]
  10813.  
  10814. set opts [list]
  10815.  
  10816. if {![BWidget::using ttk]} {
  10817. set bg [$path cget -background]
  10818. lappend opts -background $bg
  10819. $path configure -background $bg
  10820. $frame configure -background $bg
  10821. }
  10822.  
  10823. if {[set bitmap [Widget::getoption $path -image]] != ""} {
  10824. eval [list label $path.label -image $bitmap] $opts
  10825. } elseif {[set bitmap [Widget::getoption $path -bitmap]] != ""} {
  10826. eval [list label $path.label -bitmap $bitmap] $opts
  10827. }
  10828. if {[Widget::getoption $path -separator]} {
  10829. eval [list Separator::create $path.sep -orient $orient] $opts
  10830. }
  10831.  
  10832. Widget::getVariable $path data
  10833. set data(nbut)     0
  10834. set data(realized) 0
  10835.  
  10836. bind $path <Return> [list Dialog::ok $path]
  10837. bind $path <Escape> [list Dialog::cancel $path]
  10838.  
  10839. return [Widget::create Dialog $path]
  10840. }
  10841.  
  10842.  
  10843. proc Dialog::configure { path args } {
  10844. set res [Widget::configure $path $args]
  10845.  
  10846. if { [Widget::hasChanged $path -title title] } {
  10847. wm title $path $title
  10848. }
  10849. if { [Widget::hasChanged $path -background bg] } {
  10850. if { [winfo exists $path.label] } {
  10851. $path.label configure -background $bg
  10852. }
  10853. if { [winfo exists $path.sep] } {
  10854. Separator::configure $path.sep -background $bg
  10855. }
  10856. }
  10857. return $res
  10858. }
  10859.  
  10860.  
  10861. proc Dialog::cget { path option } {
  10862. return [Widget::cget $path $option]
  10863. }
  10864.  
  10865.  
  10866. proc Dialog::getframe { path } {
  10867. return $path.frame
  10868. }
  10869.  
  10870.  
  10871. proc Dialog::add { path args } {
  10872. Widget::getVariable $path data
  10873.  
  10874. set idx $data(nbut)
  10875. set cmd [list ButtonBox::add $path.bbox  -command [list Dialog::enddialog $path $idx]]
  10876. set res [eval $cmd -value $idx $args]
  10877. incr data(nbut)
  10878. return $res
  10879. }
  10880.  
  10881.  
  10882. proc Dialog::itemconfigure { path index args } {
  10883. return [eval [list ButtonBox::itemconfigure $path.bbox $index] $args]
  10884. }
  10885.  
  10886.  
  10887. proc Dialog::itemcget { path index option } {
  10888. return [ButtonBox::itemcget $path.bbox $index $option]
  10889. }
  10890.  
  10891.  
  10892. proc Dialog::invoke { path index } {
  10893. ButtonBox::invoke $path.bbox $index
  10894. }
  10895.  
  10896.  
  10897. proc Dialog::setfocus { path index } {
  10898. ButtonBox::setfocus $path.bbox $index
  10899. }
  10900.  
  10901.  
  10902. proc Dialog::enddialog { path result {destroy 0} } {
  10903. Widget::getVariable $path data
  10904.  
  10905. if {$result ne -1} {
  10906. if {[ButtonBox::index $path.bbox $result] > -1} {
  10907. set result [ButtonBox::itemcget $path.bbox $result -value]
  10908. }
  10909. }
  10910.  
  10911. set data(result) $result
  10912.  
  10913. event generate $path <<DialogEnd>>
  10914.  
  10915. if {$destroy} {
  10916. destroy $path
  10917. }
  10918.  
  10919. return $result
  10920. }
  10921.  
  10922.  
  10923. proc Dialog::draw { path {focus ""} {overrideredirect 0} {geometry ""} } {
  10924. Widget::getVariable $path data
  10925.  
  10926. set parent [Widget::getoption $path -parent]
  10927. if {!$data(realized)} {
  10928. set data(realized) 1
  10929. if {[llength [winfo children $path.bbox]]} {
  10930. set side [Widget::getoption $path -side]
  10931. if {[string equal $side "left"] || [string equal $side "right"]} {
  10932. set pad  -padx
  10933. set fill y
  10934. } else {
  10935. set pad  -pady
  10936. set fill x
  10937. }
  10938.  
  10939. pack $path.bbox -side $side  -anchor [Widget::getoption $path -anchor] -padx 1m -pady {5 10}
  10940.  
  10941. if {[winfo exists $path.sep]} {
  10942. pack $path.sep -side $side -fill $fill $pad 2m
  10943. }
  10944. }
  10945.  
  10946. if {[winfo exists $path.label]} {
  10947. pack $path.label -side left -anchor n -padx {10 5} -pady 3m
  10948. }
  10949.  
  10950. pack $path.frame -padx 1m -pady 1m -fill both -expand yes
  10951. }
  10952.  
  10953. if {![string length $geometry]} {
  10954. set geometry [Widget::getoption $path -geometry]
  10955. }
  10956.  
  10957. set width    0
  10958. set height   0
  10959. set place    [Widget::getoption $path -place]
  10960. set usePlace [expr ![string equal $place "none"]]
  10961. if {[string length $geometry]} {
  10962. set split [split $geometry x+-]
  10963.  
  10964. if {[llength $split] > 2} {
  10965. set usePlace 0
  10966. } else {
  10967. BWidget::lassign $split width height
  10968. }
  10969. }
  10970.  
  10971. wm geometry $path $geometry
  10972.  
  10973. if {$usePlace} {
  10974. set relative [Widget::getoption $path -placerelative]
  10975. if {$relative && [winfo exists $parent]} {
  10976. BWidget::place $path $width $height $place $parent
  10977. } else {
  10978. BWidget::place $path $width $height $place
  10979. }
  10980. }
  10981.  
  10982. update idletasks
  10983. wm overrideredirect $path $overrideredirect
  10984. wm deiconify $path
  10985.  
  10986. if {![winfo exists $parent] ||  ([wm state [winfo toplevel $parent]] != "withdrawn")} {
  10987. tkwait visibility $path
  10988. }
  10989.  
  10990. BWidget::focus set $path
  10991. if {[winfo exists $focus]} {
  10992. focus -force $focus
  10993. } else {
  10994. ButtonBox::setfocus $path.bbox default
  10995. }
  10996.  
  10997. if {[set grab [Widget::cget $path -modal]] != "none"} {
  10998. BWidget::grab $grab $path
  10999. set res [Dialog::wait $path]
  11000. withdraw $path
  11001. return $res
  11002. }
  11003.  
  11004. return
  11005. }
  11006.  
  11007.  
  11008. proc Dialog::wait { path } {
  11009. Widget::getVariable $path data
  11010.  
  11011. if {[info exists data(result)]} { unset data($result) }
  11012.  
  11013. tkwait variable [Widget::widgetVar $path data(result)]
  11014. if {[info exists data(result)]} {
  11015. set res $data(result)
  11016. unset data(result)
  11017. } else {
  11018. set res -1
  11019. }
  11020.  
  11021. return $res
  11022. }
  11023.  
  11024.  
  11025. proc Dialog::withdraw { path } {
  11026. BWidget::grab release $path
  11027. BWidget::focus release $path
  11028. if {[winfo exists $path]} {
  11029. wm withdraw $path
  11030. }
  11031. }
  11032.  
  11033.  
  11034. proc Dialog::ok { path } {
  11035. ButtonBox::invoke $path.bbox default
  11036. }
  11037.  
  11038.  
  11039. proc Dialog::cancel { path } {
  11040. ButtonBox::invoke $path.bbox [Widget::getoption $path -cancel]
  11041. }
  11042.  
  11043.  
  11044. proc Dialog::_destroy { path } {
  11045. BWidget::grab  release $path
  11046. BWidget::focus release $path
  11047. Widget::destroy $path
  11048. }
  11049.  
  11050.  
  11051. namespace eval ScrolledWindow {
  11052. Widget::define ScrolledWindow scrollw
  11053.  
  11054. Widget::tkinclude ScrolledWindow frame :cmd  remove { -class -colormap -visual }
  11055.  
  11056. Widget::declare ScrolledWindow {
  11057. {-class       String     "ScrolledWindow" 1}
  11058. {-scrollbar   Enum     both 0 {none both vertical horizontal}}
  11059. {-auto          Enum     both 0 {none both vertical horizontal}}
  11060. {-sides          Enum     se   0 {ne en nw wn se es sw ws}}
  11061. {-size          Int     0    1 "%d >= 0"}
  11062. {-ipad          Int     1    1 "%d >= 0"}
  11063. {-managed     Boolean     1    1}
  11064. }
  11065.  
  11066. bind ScrolledWindow <Map>     [list ScrolledWindow::_realize %W]
  11067. bind ScrolledWindow <Destroy> [list ScrolledWindow::_destroy %W]
  11068. }
  11069.  
  11070.  
  11071. proc ScrolledWindow::create { path args } {
  11072. Widget::initArgs ScrolledWindow $args maps
  11073.  
  11074. array set _args $args
  11075. set class ScrolledWindow
  11076. if {[info exists _args(-class)]} { set class $_args(-class) }
  11077.  
  11078. eval [list frame $path -class $class] $maps(:cmd)
  11079.  
  11080. Widget::initFromODB ScrolledWindow $path $args
  11081.  
  11082. Widget::getVariable $path data
  11083.  
  11084. if {![string equal $class "ScrolledWindow"]} {
  11085. set top [winfo toplevel $path]
  11086. bindtags $path [list $path $class ScrolledWindow $top all]
  11087. }
  11088.  
  11089. set bg [$path cget -background]
  11090.  
  11091. if {[BWidget::using ttk]} {
  11092. ttk::scrollbar $path.vscroll
  11093. ttk::scrollbar $path.hscroll -orient horizontal
  11094. } else {
  11095. scrollbar $path.hscroll  -highlightthickness 0 -takefocus 0  -orient     horiz     -relief     sunken     -bg     $bg
  11096. scrollbar $path.vscroll  -highlightthickness 0 -takefocus 0  -orient     vert     -relief     sunken     -bg     $bg
  11097. }
  11098.  
  11099. set data(vmin)     -1
  11100. set data(vmax)     -1
  11101. set data(hmin)     -1
  11102. set data(hmax)     -1
  11103.  
  11104. set data(afterId)  ""
  11105. set data(realized) 0
  11106.  
  11107. _setData $path  [Widget::cget $path -scrollbar]  [Widget::cget $path -auto]  [Widget::cget $path -sides]
  11108.  
  11109. if {[Widget::cget $path -managed]} {
  11110. set data(hsb,packed) $data(hsb,present)
  11111. set data(vsb,packed) $data(vsb,present)
  11112. } else {
  11113. set data(hsb,packed) 0
  11114. set data(vsb,packed) 0
  11115. }
  11116.  
  11117. if {![BWidget::using ttk]} {
  11118. set sbsize [Widget::cget $path -size]
  11119.  
  11120. if {$sbsize} {
  11121. $path.vscroll configure -width $sbsize
  11122. $path.hscroll configure -width $sbsize
  11123. }
  11124. }
  11125.  
  11126. set data(ipad) [Widget::cget $path -ipad]
  11127.  
  11128. if {$data(hsb,packed)} {
  11129. grid $path.hscroll -column 1 -row $data(hsb,row)  -sticky ew -ipady $data(ipad)
  11130. }
  11131. if {$data(vsb,packed)} {
  11132. grid $path.vscroll -column $data(vsb,column) -row 1  -sticky ns -ipadx $data(ipad)
  11133. }
  11134.  
  11135. grid columnconfigure $path 1 -weight 1
  11136. grid rowconfigure     $path 1 -weight 1
  11137.  
  11138. return [Widget::create ScrolledWindow $path]
  11139. }
  11140.  
  11141.  
  11142. proc ScrolledWindow::getframe { path } {
  11143. return $path
  11144. }
  11145.  
  11146.  
  11147. proc ScrolledWindow::setwidget { path widget } {
  11148. Widget::getVariable $path data
  11149.  
  11150. if {[info exists data(widget)] && [winfo exists $data(widget)]
  11151. && ![string equal $data(widget) $widget]} {
  11152. grid remove $data(widget)
  11153. $data(widget) configure -xscrollcommand "" -yscrollcommand ""
  11154. }
  11155.  
  11156. set data(widget) $widget
  11157. grid $widget -in $path -row 1 -column 1 -sticky news
  11158.  
  11159. $path.hscroll configure -command [list $widget xview]
  11160. $path.vscroll configure -command [list $widget yview]
  11161. $widget configure  -xscrollcommand [list ScrolledWindow::_set_hscroll $path]  -yscrollcommand [list ScrolledWindow::_set_vscroll $path]
  11162. }
  11163.  
  11164.  
  11165. proc ScrolledWindow::getwidget { path } {
  11166. Widget::getVariable $path data
  11167. if {[info exists data(widget)]} { return $data(widget) }
  11168. }
  11169.  
  11170.  
  11171. proc ScrolledWindow::configure { path args } {
  11172. Widget::getVariable $path data
  11173.  
  11174. set res [Widget::configure $path $args]
  11175.  
  11176. if {[Widget::hasChanged $path -background bg]} {
  11177. catch { $path.hscroll configure -background $bg }
  11178. catch { $path.vscroll configure -background $bg }
  11179. }
  11180.  
  11181. if {[Widget::hasChanged $path -scrollbar scrollbar]
  11182. || [Widget::hasChanged $path -auto  auto]
  11183. || [Widget::hasChanged $path -sides sides]} {
  11184. _setData $path $scrollbar $auto $sides
  11185.  
  11186. BWidget::lassign [$path.hscroll get] vmin vmax
  11187. set data(hsb,packed) [expr {$data(hsb,present) &&  (!$data(hsb,auto) || ($vmin != 0 || $vmax != 1))}]
  11188.  
  11189. BWidget::lassign [$path.vscroll get] vmin vmax
  11190. set data(vsb,packed) [expr {$data(vsb,present) &&  (!$data(vsb,auto) || ($vmin != 0 || $vmax != 1))}]
  11191.  
  11192. set data(ipad) [Widget::cget $path -ipad]
  11193.  
  11194. if {$data(hsb,packed)} {
  11195. grid $path.hscroll -column 1 -row $data(hsb,row)  -sticky ew -ipady $data(ipad)
  11196. }
  11197. if {$data(vsb,packed)} {
  11198. grid $path.vscroll -column $data(vsb,column) -row 1  -sticky ns -ipadx $data(ipad)
  11199. }
  11200. }
  11201. return $res
  11202. }
  11203.  
  11204.  
  11205. proc ScrolledWindow::cget { path option } {
  11206. return [Widget::cget $path $option]
  11207. }
  11208.  
  11209.  
  11210. proc ScrolledWindow::_set_hscroll { path vmin vmax } {
  11211. Widget::getVariable $path data
  11212.  
  11213. $path.hscroll set $vmin $vmax
  11214.  
  11215. set data(hmin) $vmin
  11216. set data(hmax) $vmax
  11217.  
  11218. _redraw_after $path
  11219. }
  11220.  
  11221.  
  11222. proc ScrolledWindow::_set_vscroll { path vmin vmax } {
  11223. Widget::getVariable $path data
  11224.  
  11225. $path.vscroll set $vmin $vmax
  11226.  
  11227. set data(vmin) $vmin
  11228. set data(vmax) $vmax
  11229.  
  11230. _redraw_after $path
  11231. }
  11232.  
  11233.  
  11234. proc ScrolledWindow::_setData {path scrollbar auto sides} {
  11235. Widget::getVariable $path data
  11236.  
  11237. set sb    [lsearch -exact {none horizontal vertical both} $scrollbar]
  11238. set auto  [lsearch -exact {none horizontal vertical both} $auto]
  11239.  
  11240. set data(hsb,present)  [expr {($sb & 1) != 0}]
  11241. set data(hsb,auto)       [expr {($auto & 1) != 0}]
  11242. set data(hsb,row)       [expr {[string match *n* $sides] ? 0 : 2}]
  11243.  
  11244. set data(vsb,present)  [expr {($sb & 2) != 0}]
  11245. set data(vsb,auto)       [expr {($auto & 2) != 0}]
  11246. set data(vsb,column)   [expr {[string match *w* $sides] ? 0 : 2}]
  11247. }
  11248.  
  11249.  
  11250. proc ScrolledWindow::_redraw_after { path } {
  11251. Widget::getVariable $path data
  11252. after cancel $data(afterId)
  11253. set data(afterId) [after 5 [list ScrolledWindow::_redraw $path]]
  11254. }
  11255.  
  11256.  
  11257. proc ScrolledWindow::_redraw { path } {
  11258. if {![Widget::exists $path]} { return }
  11259.  
  11260. Widget::getVariable $path data
  11261.  
  11262. if {!$data(realized)} { return }
  11263.  
  11264. if {$data(hsb,present) && $data(hsb,auto)} {
  11265. if {$data(hsb,packed) && $data(hmin) == 0 && $data(hmax) == 1} {
  11266. set data(hsb,packed) 0
  11267. grid remove $path.hscroll
  11268. } elseif {!$data(hsb,packed) && ($data(hmin)!=0 || $data(hmax)!=1)} {
  11269. set data(hsb,packed) 1
  11270. grid $path.hscroll -column 1 -row $data(hsb,row)  -sticky ew -ipady $data(ipad)
  11271. }
  11272. }
  11273.  
  11274. if {$data(vsb,present) && $data(vsb,auto)} {
  11275. if {$data(vsb,packed) && $data(vmin) == 0 && $data(vmax) == 1} {
  11276. set data(vsb,packed) 0
  11277. grid remove $path.vscroll
  11278. } elseif {!$data(vsb,packed) && ($data(vmin)!=0 || $data(vmax)!=1) } {
  11279. set data(vsb,packed) 1
  11280. grid $path.vscroll -column $data(vsb,column) -row 1  -sticky ns -ipadx $data(ipad)
  11281. }
  11282. }
  11283. }
  11284.  
  11285.  
  11286. proc ScrolledWindow::_realize { path } {
  11287. Widget::getVariable $path data
  11288. set data(realized) 1
  11289. }
  11290.  
  11291.  
  11292. proc ScrolledWindow::_destroy { path } {
  11293. Widget::getVariable $path data
  11294. after cancel $data(afterId)
  11295. Widget::destroy $path
  11296. }
  11297.  
  11298.  
  11299. if {0} {
  11300.  
  11301. IconLibrary icons
  11302.  
  11303. icons load -find 1 -directory $kdedir -extension png -findgroups  [list {actions act} {apps app} {devices dev}
  11304. {filesystems file} {mimetypes mime}]
  11305. }
  11306.  
  11307.  
  11308. package require Tcl 8.4
  11309.  
  11310. namespace eval IconLibrary {
  11311. Widget::define IconLibrary icons
  11312.  
  11313. Widget::declare IconLibrary {
  11314. {-file          String    "tkIcons"                 0}
  11315. {-icons         String    ""                        0}
  11316. {-sizes         String    ""                        0}
  11317. {-groups        String    ""                        0}
  11318. {-create        Boolean   0                         0}
  11319. {-directory     String    ""                        0}
  11320.  
  11321. {-find          Boolean   0                         0}
  11322. {-extension     String    "gif"                     0}
  11323. {-findsizes     String    "16 22"                   0}
  11324. {-findgroups    String    "act app dev file mime"   0}
  11325. }
  11326.  
  11327. namespace eval Icon {
  11328. Widget::declare IconLibrary::Icon {
  11329. {-size      String    ""                        1}
  11330. {-type      String    ""                        1}
  11331. {-file      String    ""                        1}
  11332. {-data      String    ""                        1}
  11333. {-image     String    ""                        1}
  11334. {-imageargs String    ""                        1}
  11335. {-filegroup String    ""                        1}
  11336. {-workgroup String    ""                        1}
  11337. }
  11338. }
  11339.  
  11340. namespace eval NamesArgs {
  11341. Widget::declare IconLibrary::NamesArgs {
  11342. {-icons         String    ""                        0}
  11343. {-sizes         String    ""                        0}
  11344. {-groups        String    ""                        0}
  11345. }
  11346. }
  11347.  
  11348. variable  sizeMap
  11349. array set sizeMap {
  11350. 16x16   16
  11351. 22x22   22
  11352. 32x32   32
  11353. 48x48   48
  11354. 64x64   64
  11355. 128x128 128
  11356. }
  11357.  
  11358. variable  groupMapArray
  11359. array set groupMapArray {
  11360. apps            app
  11361. actions         act
  11362. devices         dev
  11363. mimetypes       mime
  11364. filesystems     file
  11365. }
  11366.  
  11367. variable groupMap
  11368.  
  11369. foreach name [array names groupMapArray] {
  11370. lappend groupMap [list $name $groupMapArray($name)]
  11371. }
  11372. }
  11373.  
  11374.  
  11375. proc IconLibrary::create { library args } {
  11376. Widget::init IconLibrary $library $args
  11377.  
  11378. Widget::getVariable $library data
  11379.  
  11380. set data(icons) [list]
  11381.  
  11382. if {[llength $args]} { eval [list IconLibrary::load $library] $args }
  11383.  
  11384. return [Widget::create IconLibrary $library 0]
  11385. }
  11386.  
  11387.  
  11388. proc IconLibrary::load { library args } {
  11389. Widget::getVariable $library data
  11390.  
  11391. Widget::init IconLibrary $library $args
  11392.  
  11393. set file      [Widget::getoption $library -file]
  11394. set create    [Widget::getoption $library -create]
  11395. set iconlist  [Widget::getoption $library -icons]
  11396. set sizelist  [Widget::getoption $library -sizes]
  11397. set grouplist [Widget::getoption $library -groups]
  11398. set directory [Widget::getoption $library -directory]
  11399.  
  11400. set filename $file
  11401. if {![string length $directory]} {
  11402. set directory [file dirname $file]
  11403. } elseif {[string length $file]} {
  11404. set filename [file join $directory $file]
  11405. }
  11406.  
  11407. if {[Widget::getoption $library -find]} {
  11408. if {![string length $directory]} {
  11409. return -code error "cannot find images without -directory"
  11410. }
  11411.  
  11412. set ext        [Widget::getoption $library -extension]
  11413. set findsizes  [Widget::getoption $library -findsizes]
  11414. set findgroups [Widget::getoption $library -findgroups]
  11415.  
  11416. foreach size $findsizes {
  11417. set size  [IconLibrary::_get_size $size]
  11418.  
  11419. set sizedir [file join $directory $size]
  11420. if {![file exists $sizedir]} { continue }
  11421.  
  11422. foreach group $findgroups {
  11423. set filegroup [lindex $group 0]
  11424. set workgroup [lindex $group 1]
  11425. if {[llength $group] == 1} { set workgroup $filegroup }
  11426.  
  11427. set groupdir [file join $sizedir $filegroup]
  11428. if {![file exists $groupdir]} { continue }
  11429.  
  11430. foreach imagefile [glob -nocomplain -dir $groupdir *.$ext] {
  11431. set image [file root [file tail $imagefile]]
  11432. set image $workgroup$image$size
  11433. lappend data(icons) $image
  11434.  
  11435. set icon $library#$image
  11436. set exists [expr {[Widget::exists $icon]
  11437. && [string length [Widget::getoption $icon -image]]}]
  11438.  
  11439. Widget::init IconLibrary::Icon $icon  [list -size $size -type file -file $imagefile  -filegroup $filegroup -workgroup $workgroup  -data "" -image ""]
  11440.  
  11441. if {$exists && !$create} {
  11442. IconLibrary::image $library $image
  11443. }
  11444. }
  11445. }
  11446. }
  11447.  
  11448. if {![file exists $filename]} {
  11449. if {$create} { _create_icons $library $data(icons) }
  11450. set data(icons) [lsort -unique $data(icons)]
  11451. return $data(icons)
  11452. }
  11453. }
  11454.  
  11455. if {![file isfile $filename] || ![file readable $filename]} {
  11456. return -code error "couldn't open \"$filename\": no such file"
  11457. }
  11458.  
  11459. set iLen [llength $iconlist]
  11460. set sLen [llength $sizelist]
  11461. set gLen [llength $grouplist]
  11462.  
  11463. set fp [open $filename]
  11464.  
  11465. while {[gets $fp line] != -1} {
  11466. if {[string equal [string index $line 0] "#"]} { continue }
  11467.  
  11468. set list [split $line :]
  11469. if {[llength $list] < 5} { continue }
  11470.  
  11471. BWidget::lassign $list image workgroup filegroup size type imagedata
  11472. set size [IconLibrary::_get_size_int $size]
  11473.  
  11474. if {($gLen && [lsearch -exact $grouplist $workgroup] < 0)
  11475. || ($sLen && [lsearch -exact $sizelist $size] < 0)
  11476. || ($iLen && [lsearch -exact $iconlist $image] < 0)} { continue }
  11477.  
  11478. set file ""
  11479. if {[string equal $type "file"]} {
  11480. if {![string length $imagedata]} { continue }
  11481.  
  11482. if {[string is integer $size]} { set size ${size}x${size} }
  11483. set file [file join $directory $size $filegroup $imagedata]
  11484. set images($image,file) $file
  11485. }
  11486.  
  11487. lappend data(icons) $image
  11488.  
  11489. set icon $library#$image
  11490. set exists [expr {[Widget::exists $icon]
  11491. && [string length [Widget::getoption $icon -image]]}]
  11492.  
  11493. Widget::init IconLibrary::Icon $icon  [list -size $size -type $type -file $file -data $imagedata  -filegroup $filegroup -workgroup $workgroup -image ""]
  11494.  
  11495. if {$exists && !$create} {
  11496. IconLibrary::image $library $image
  11497. }
  11498. }
  11499.  
  11500. close $fp
  11501.  
  11502. if {$create} { _create_icons $library $icons }
  11503.  
  11504. set data(icons) [lsort -unique $data(icons)]
  11505. }
  11506.  
  11507.  
  11508. proc IconLibrary::cget { library option } {
  11509. return [Widget::cget $library $option]
  11510. }
  11511.  
  11512.  
  11513. proc IconLibrary::configure { library args } {
  11514. return [Widget::configure $library $args]
  11515. }
  11516.  
  11517.  
  11518. proc IconLibrary::itemcget { library image option } {
  11519. if {![IconLibrary::exists $library $image]} {
  11520. return -code error "no such icon '$image'"
  11521. }
  11522.  
  11523. set path    $library#$image
  11524. set image   [Widget::getoption $path -image]
  11525. set created [string length $image]
  11526. if {$created && ($option eq "-file" || $option eq "-data")} {
  11527. return [$image cget $option]
  11528. }
  11529. return [Widget::cget $path $option]
  11530. }
  11531.  
  11532.  
  11533. proc IconLibrary::itemconfigure { library image args } {
  11534. if {![IconLibrary::exists $library $image]} {
  11535. return -code error "no such icon '$image'"
  11536. }
  11537.  
  11538. set path    $library#$image
  11539. set image   [Widget::getoption $path -image]
  11540. set created [string length $image]
  11541.  
  11542. if {![llength $args]} {
  11543. set return [list]
  11544. foreach list [Widget::configure $path $args] {
  11545. set option [lindex $list 0]
  11546. if {$created && ($option eq "-file" || $option eq "-data")} {
  11547. lappend return [$image configure $option]
  11548. } else {
  11549. lappend return $list
  11550. }
  11551. }
  11552. return $return
  11553. } elseif {[llength $args] == 1} {
  11554. set option [lindex $args 0]
  11555. if {$created && ($option eq "-file" || $option eq "-data")} {
  11556. return [$image configure $option]
  11557. } else {
  11558. return [Widget::configure $path $option]
  11559. }
  11560. }
  11561.  
  11562. set imageOpts  [list]
  11563. set widgetOpts [list]
  11564. foreach [list option value] $args {
  11565. if {$created && ($option eq "-file" || $option eq "-data")} {
  11566. lappend imageOpts $option $value
  11567. } else {
  11568. lappend widgetOpts $option $value
  11569. }
  11570. }
  11571.  
  11572. if {[llength $imageOpts]} {
  11573. eval [list $image configure] $imageOpts
  11574. }
  11575.  
  11576. if {[llength $widgetOpts]} {
  11577. Widget::configure $path $widgetOpts
  11578. }
  11579. }
  11580.  
  11581.  
  11582. proc IconLibrary::exists { library image } {
  11583. return [Widget::exists $library#$image]
  11584. }
  11585.  
  11586.  
  11587. proc IconLibrary::icons { library {pattern ""} } {
  11588. Widget::getVariable $library data
  11589. if {![string length $pattern]} { return $data(icons) }
  11590. return [lsearch -glob -all -inline $data(icons) $pattern]
  11591. }
  11592.  
  11593.  
  11594. proc IconLibrary::add { library image args } {
  11595. Widget::getVariable $library data
  11596.  
  11597. if {[IconLibrary::exists $library $image]} {
  11598. return -code error "icon \"$image\" already exists"
  11599. }
  11600.  
  11601. array set _args $args
  11602.  
  11603. set create 0
  11604. if {[info exists _args(-create)]} {
  11605. if {$_args(-create)} { set create 1 }
  11606. unset _args(-create)
  11607. }
  11608.  
  11609. Widget::init IconLibrary::Icon $library#$image [array get _args]
  11610. lappend data(icons) $image
  11611.  
  11612. if {$create} { IconLibrary::image $library $image }
  11613.  
  11614. return $image
  11615. }
  11616.  
  11617.  
  11618. proc IconLibrary::image { library image } {
  11619. Widget::getVariable $library images
  11620.  
  11621. if {![IconLibrary::exists $library $image]} {
  11622. return -code error "no such icon '$image'"
  11623. }
  11624.  
  11625. set path $library#$image
  11626.  
  11627. if {[string equal [Widget::getoption $path -type] "icon"]} {
  11628. set icon  $image
  11629. set image [Widget::getoption $path -data]
  11630. set path  $library#$image
  11631. if {![IconLibrary::exists $library $image]} {
  11632. return -code error "no such icon '$image' while loading '$icon'"
  11633. }
  11634. }
  11635.  
  11636. if {![string length [Widget::getoption $path -image]]} {
  11637. set img ::Icons::${library}::$image
  11638.  
  11639. set data [Widget::getoption $path -data]
  11640. set file [Widget::getoption $path -file]
  11641. set args [Widget::getoption $path -imageargs]
  11642.  
  11643. if {[string length $data]} {
  11644. lappend args -data $data
  11645. } elseif {[string length $file]} {
  11646. lappend args -file $file
  11647. }
  11648.  
  11649. eval [list ::image create photo $img] $args
  11650.  
  11651. Widget::setoption $path -image $img -file "" -data ""
  11652. }
  11653.  
  11654. return [Widget::getoption $path -image]
  11655. }
  11656.  
  11657.  
  11658. proc IconLibrary::delete { library args } {
  11659. Widget::getVariable $library data
  11660.  
  11661. set images [list]
  11662. foreach icon $args {
  11663. set image [Widget::getoption $library#$icon -image]
  11664. if {[string length $image]} { lappend images $image }
  11665. Widget::destroy $library#$icon 0
  11666. }
  11667.  
  11668. if {[llength $images]} { eval ::image delete $images }
  11669.  
  11670. set data(icons) [eval [list BWidget::lremove $data(icons)] $args]
  11671.  
  11672. return
  11673. }
  11674.  
  11675.  
  11676. proc IconLibrary::clear { library } {
  11677. Widget::getVariable $library data
  11678. eval [list IconLibrary::delete $library] $data(icons)
  11679. }
  11680.  
  11681.  
  11682. proc IconLibrary::destroy { library } {
  11683. IconLibrary::clear $library
  11684. Widget::destroy $library
  11685. }
  11686.  
  11687.  
  11688. proc IconLibrary::_get_size { size } {
  11689. if {[string is integer -strict $size]} { return ${size}x${size} }
  11690. return $size
  11691. }
  11692.  
  11693.  
  11694. proc IconLibrary::_get_size_int { size } {
  11695. variable sizeMap
  11696. if {[info exists sizeMap($size)]} { return $sizeMap($size) }
  11697. if {[scan $size "%dx%d" w h] == 2 && $w == $h} { return $w }
  11698. return $size
  11699. }
  11700.  
  11701.  
  11702. proc IconLibrary::_create_icons { library icons } {
  11703. foreach icon $icons {
  11704. IconLibrary::image $library $icon
  11705. }
  11706. }
  11707.  
  11708. namespace eval ChooseDirectory {
  11709. Widget::define ChooseDirectory choosedir Dialog ScrolledWindow  Tree IconLibrary
  11710.  
  11711. Widget::bwinclude ChooseDirectory Dialog :cmd
  11712.  
  11713. Widget::declare ChooseDirectory {
  11714. {-name       String   ""        1}
  11715. {-message    String   "Please choose a directory, then select OK." 0}
  11716. {-folders    String   ""        0}
  11717. {-initialdir String   ""        0}
  11718. }
  11719.  
  11720. bind ChooseDirectory <Destroy> [list ChooseDirectory::_destroy %W]
  11721. }
  11722.  
  11723.  
  11724. proc ChooseDirectory::create { path args } {
  11725. variable dialogs
  11726.  
  11727. BWidget::LoadBWidgetIconLibrary
  11728.  
  11729. set dialog $path#choosedir
  11730.  
  11731. array set maps [Widget::splitArgs $args Dialog ChooseDirectory]
  11732.  
  11733. Widget::initFromODB ChooseDirectory $dialog $maps(ChooseDirectory)
  11734.  
  11735. Widget::getVariable $dialog nodes
  11736. set nodes(count) 0
  11737.  
  11738. eval [list Dialog::create $path -class ChooseDirectory  -anchor e -default 1 -cancel 2 -modal local -spacing 5 -homogeneous 0  -title "Browse for Folder" -geometry 340x300] $maps(:cmd) $maps(Dialog)
  11739. wm protocol $path WM_DELETE_WINDOW [list $path cancel]
  11740.  
  11741. set frame [Dialog::getframe $path]
  11742.  
  11743. grid rowconfigure    $frame 3 -weight 1
  11744. grid columnconfigure $frame 0 -weight 1
  11745.  
  11746. Label $frame.message -anchor w -autowrap 1 -justify left  -text [Widget::getoption $dialog -message]
  11747. grid  $frame.message -row 0 -column 0 -sticky new -pady 5
  11748.  
  11749. Label $frame.dirlabel -anchor w -elide 1 -elideside center  -textvariable [Widget::widgetVar $path root]
  11750. grid  $frame.dirlabel -row 1 -column 0 -sticky new -pady 5
  11751.  
  11752. if {[BWidget::using ttk]} {
  11753. ttk::entry $frame.e -textvariable [Widget::widgetVar $path tail]
  11754. } else {
  11755. entry $frame.e -textvariable [Widget::widgetVar $path tail]
  11756. }
  11757. grid  $frame.e -row 2 -column 0 -sticky ew -pady 2 -padx 1
  11758. bind $frame.e <Key> [list ChooseDirectory::_update_ok_button $path]
  11759.  
  11760. ScrolledWindow $frame.sw
  11761. grid $frame.sw -row 3 -column 0 -sticky news
  11762.  
  11763. set tree $frame.tree
  11764. Tree $tree -width 35  -opencmd  [list ChooseDirectory::_open_directory $path $tree]  -closecmd [list ChooseDirectory::_close_directory $path $tree]
  11765.  
  11766. $frame.sw setwidget $tree
  11767.  
  11768. $tree bindText  <1> [list ChooseDirectory::_select_directory $path $tree]
  11769. $tree bindImage <1> [list ChooseDirectory::_select_directory $path $tree]
  11770.  
  11771. $tree bindText  <Double-1> [list Tree::toggle $tree]
  11772. $tree bindImage <Double-1> [list Tree::toggle $tree]
  11773.  
  11774. Dialog::add $path -text " Make New Folder " -spacing 20  -command [list ChooseDirectory::_create_directory $path $tree]
  11775. Dialog::add $path -name ok     -width 12
  11776. Dialog::add $path -name cancel -width 12
  11777.  
  11778. set folders [Widget::getoption $dialog -folders]
  11779. if {![llength $folders]} {
  11780. set desktop   [file normalize [file join ~ Desktop]]
  11781. set documents [file normalize [file join ~ Documents]]
  11782. if {[info exists ::env(HOME)]} {
  11783. set desktopText Desktop
  11784.  
  11785. if {$::tcl_platform(platform) eq "windows"} {
  11786. set documentsText "My Documents"
  11787. } else {
  11788. set documentsText "Documents"
  11789. }
  11790.  
  11791. set desktop   [file join $::env(HOME) $desktopText]
  11792. set documents [file join $::env(HOME) $documentsText]
  11793. }
  11794.  
  11795. if {[file exists $desktop]} {
  11796. lappend folders [list [file normalize $desktop] $desktopText]
  11797. }
  11798.  
  11799. if {[file exists $documents]} {
  11800. lappend folders [list [file normalize $documents] $documentsText]
  11801. }
  11802.  
  11803. if {$::tcl_platform(platform) eq "windows"} {
  11804. foreach volume [file volumes] {
  11805. if {[string match "?:/" $volume]} {
  11806. lappend folders [list $volume $volume]
  11807. }
  11808. }
  11809. } else {
  11810. lappend folders [list / /]
  11811. }
  11812. }
  11813.  
  11814. foreach list $folders {
  11815. set dir   [lindex $list 0]
  11816. set text  [lindex $list 1]
  11817. set image [lindex $list 2]
  11818.  
  11819. if {![string length $image]} { set image [BWidget::Icon folder16] }
  11820.  
  11821. set nodes(root,$dir) [incr nodes(count)]
  11822. $tree insert end root $nodes(root,$dir) -text $text -image $image  -data $dir -drawcross allways
  11823. }
  11824.  
  11825. set dir [Widget::getoption $dialog -initialdir]
  11826. if {![string length $dir]} { set dir [pwd] }
  11827. set dir [file normalize $dir]
  11828.  
  11829. set name [Widget::getoption $dialog -name]
  11830. if {[info exists dialogs($name)]} { set dir $dialogs($name) }
  11831.  
  11832. set dirpath [list]
  11833. foreach sub [file split $dir] {
  11834. if {![llength $dirpath]} {
  11835. set node $nodes(root,$sub)
  11836. set rootNode $node
  11837.  
  11838. lappend dirpath $sub
  11839. $tree itemconfigure $node -open 1
  11840. } else {
  11841. set parent $node
  11842. lappend dirpath $sub
  11843. set subpath [eval file join $dirpath]
  11844.  
  11845. if {![info exists nodes($rootNode,$subpath)]} {
  11846. set nodes($rootNode,$subpath) [incr nodes(count)]
  11847. $tree insert end $parent $nodes($rootNode,$subpath) -open 1  -image [BWidget::Icon folder16] -text $sub -data $subpath
  11848. }
  11849. set node $nodes($rootNode,$subpath)
  11850. }
  11851.  
  11852. ChooseDirectory::_open_directory $path $tree $node
  11853. }
  11854.  
  11855. _select_directory $path $tree $node
  11856.  
  11857. $frame.e selection range 0 end
  11858.  
  11859. set result [Dialog::draw $path $frame.e]
  11860.  
  11861. Widget::getVariable $path root
  11862. Widget::getVariable $path tail
  11863. set dirroot $root
  11864. set dirtail $tail
  11865.  
  11866. destroy $path
  11867.  
  11868. if {$result == 2} { return }
  11869.  
  11870. if {$dirtail ne [file tail $dirroot]} {
  11871. set dirroot [file join $dirroot $dirtail]
  11872. }
  11873.  
  11874. if {[string length $name]} { set dialogs($name) $dirroot }
  11875.  
  11876. return $dirroot
  11877. }
  11878.  
  11879.  
  11880. proc ChooseDirectory::_select_directory { path tree node } {
  11881. Widget::getVariable $path root
  11882. Widget::getVariable $path tail
  11883.  
  11884. $tree see $node
  11885. $tree selection set $node
  11886.  
  11887. set dir  [$tree itemcget $node -data]
  11888. set root $dir
  11889. set tail [file tail $dir]
  11890. }
  11891.  
  11892.  
  11893. proc ChooseDirectory::_open_directory { path tree node } {
  11894. Widget::getVariable $path#choosedir nodes
  11895.  
  11896. set parent   [$tree parent $node]
  11897. set rootNode $node
  11898. while {$parent ne "root"} {
  11899. set rootNode $parent
  11900. set parent   [$tree parent $parent]
  11901. }
  11902.  
  11903. set sort -ascii
  11904. if {$::tcl_platform(platform) eq "windows"} { set sort -dict }
  11905.  
  11906. set rootdir [$tree itemcget $node -data]
  11907.  
  11908. set dirs [glob -nocomplain -type d -dir $rootdir *]
  11909. eval lappend dirs [glob -nocomplain -type {d hidden} -dir $rootdir *]
  11910.  
  11911. set found 0
  11912. foreach dir [lsort $sort $dirs] {
  11913. set tail [file tail $dir]
  11914. if {$tail eq "." || $tail eq ".."} { continue }
  11915.  
  11916. set found 1
  11917. if {![info exists nodes($rootNode,$dir)]} {
  11918. set nodes($rootNode,$dir) [incr nodes(count)]
  11919. $tree insert end $node $nodes($rootNode,$dir)  -drawcross allways -image [BWidget::Icon folder16]  -text [file tail $dir] -data $dir
  11920. }
  11921. }
  11922.  
  11923. set opts [list -open 1 -image [BWidget::Icon folderopen16]]
  11924.  
  11925. if {!$found} { lappend opts -drawcross never }
  11926. eval [list $tree itemconfigure $node] $opts
  11927. }
  11928.  
  11929.  
  11930. proc ChooseDirectory::_close_directory { path tree node } {
  11931. $tree itemconfigure $node -image [BWidget::Icon folder16]
  11932. }
  11933.  
  11934.  
  11935. proc ChooseDirectory::_next_directory { root text } {
  11936. set i 1
  11937. set dir [file join $root $text]
  11938. while {[file exists $dir]} {
  11939. set dir [file join $root "$text ([incr i])"]
  11940. }
  11941. return $dir
  11942. }
  11943.  
  11944.  
  11945. proc ChooseDirectory::_create_directory { path tree } {
  11946. Widget::getVariable $path root
  11947. Widget::getVariable $path#choosedir nodes
  11948.  
  11949. set sel [lindex [$tree selection get] 0]
  11950. $tree itemconfigure $sel -open 1
  11951.  
  11952. set text [_next_directory $root "New Folder"]
  11953. set i [$tree insert end $sel new#auto -text [file tail $text]  -image [BWidget::Icon folder16]]
  11954.  
  11955. $tree edit $i [file tail $text]  [list ChooseDirectory::_verify_directory $path $tree $i] 1
  11956.  
  11957. set dir [file join $root [$tree itemcget $i -text]]
  11958.  
  11959. set parent   [$tree parent $sel]
  11960. set rootNode $sel
  11961. while {$parent ne "root"} {
  11962. set rootNode $parent
  11963. set parent   [$tree parent $parent]
  11964. }
  11965.  
  11966. set nodes($rootNode,$dir) [incr nodes(count)]
  11967. set node $nodes($rootNode,$dir)
  11968.  
  11969. $tree delete $i
  11970. $tree insert end $sel $node -text [file tail $dir] -data $dir  -image [BWidget::Icon folder16]
  11971.  
  11972. _select_directory $path $tree $node
  11973.  
  11974. file mkdir $dir
  11975. }
  11976.  
  11977.  
  11978. proc ChooseDirectory::_verify_directory { path tree node newtext } {
  11979. Widget::getVariable $path root
  11980.  
  11981. set txt [$tree itemcget $node -text]
  11982. if {![string length $newtext]} { set newtext $txt }
  11983.  
  11984. set dir [file join $root $newtext]
  11985.  
  11986. if {[file exists $dir]} {
  11987. set title  "Error Renaming File or Folder"
  11988. set    msg "Cannot rename $txt: A file with the name you specified "
  11989. append msg "already exists. Specify a different file name."
  11990. tk_messageBox -icon error -title $title -message $msg
  11991. return 0
  11992. }
  11993.  
  11994. $tree itemconfigure $node -text $newtext
  11995. return 1
  11996. }
  11997.  
  11998.  
  11999. proc ChooseDirectory::_update_ok_button { path {really 0} } {
  12000. if {[Widget::exists $path]} {
  12001. if {!$really} {
  12002. after idle [concat [info level 0] 1]
  12003. } else {
  12004. Widget::getVariable $path root
  12005. Widget::getVariable $path tail
  12006. set len [llength [file split $root]]
  12007. if {[string trim $tail] eq "" && $len > 1} {
  12008. ButtonBox::itemconfigure $path.bbox 1 -state disabled
  12009. } else {
  12010. ButtonBox::itemconfigure $path.bbox 1 -state normal
  12011. }
  12012. }
  12013. }
  12014. }
  12015.  
  12016.  
  12017. proc ChooseDirectory::_destroy { path } {
  12018. Widget::destroy $path#choosedir
  12019. Widget::destroy $path
  12020. }
  12021.  
  12022.  
  12023. namespace eval MessageDlg {
  12024. Widget::define MessageDlg messagedlg Dialog
  12025.  
  12026. Widget::tkinclude MessageDlg label .frame.msg  remove {
  12027. -cursor -highlightthickness -relief -borderwidth -bd
  12028. -takefocus -textvariable
  12029. } rename {
  12030. -text -message
  12031. } initialize {
  12032. -anchor w -justify left
  12033. }
  12034.  
  12035. Widget::bwinclude MessageDlg Dialog :cmd  remove {
  12036. -modal -image -bitmap -side -anchor -separator
  12037. -homogeneous -padx -pady -spacing
  12038. }
  12039.  
  12040. Widget::declare MessageDlg {
  12041. {-name       String     ""     0}
  12042. {-icon       Enum       "info" 0 {none error info question warning}}
  12043. {-type       Enum       "user" 0
  12044. {abortretryignore ok okcancel retrycancel yesno yesnocancel user}}
  12045. {-buttons     String    ""     0}
  12046. {-buttonwidth String    0      0}
  12047. {-usenative   Boolean   1      0}
  12048. }
  12049.  
  12050. Widget::addmap MessageDlg "" tkMBox {
  12051. -parent {} -message {} -default {} -title {}
  12052. }
  12053. }
  12054.  
  12055.  
  12056. proc MessageDlg::create { path args } {
  12057. variable dialogs
  12058.  
  12059. array set _args $args
  12060.  
  12061. if {[info exists _args(-name)] && [info exists dialogs($_args(-name))]} {
  12062. return $dialogs($_args(-name))
  12063. }
  12064.  
  12065. BWidget::LoadBWidgetIconLibrary
  12066.  
  12067. set dialog "$path#Message"
  12068.  
  12069. Widget::initArgs MessageDlg $args maps
  12070. Widget::initFromODB MessageDlg $dialog $maps(MessageDlg)
  12071.  
  12072. set type   [Widget::getoption $dialog -type]
  12073. set icon   [Widget::getoption $dialog -icon]
  12074. set width  [Widget::getoption $dialog -buttonwidth]
  12075. set native [Widget::getoption $dialog -usenative]
  12076.  
  12077. set user  0
  12078. set defb  -1
  12079. set canb  -1
  12080. switch -- $type {
  12081. abortretryignore {set lbut {abort retry ignore}; set defb 0}
  12082. ok               {set lbut {ok}; set defb 0 }
  12083. okcancel         {set lbut {ok cancel}; set defb 0; set canb 1}
  12084. retrycancel      {set lbut {retry cancel}; set defb 0; set canb 1}
  12085. yesno            {set lbut {yes no}; set defb 0; set canb 1}
  12086. yesnocancel      {set lbut {yes no cancel}; set defb 0; set canb 2}
  12087. user             {
  12088. set user   1
  12089. set native 0
  12090. set lbut [Widget::cget $dialog -buttons]
  12091. }
  12092. }
  12093.  
  12094. array set dialogArgs $maps(:cmd)
  12095.  
  12096. if {!$user && ![info exists dialogArgs(-default)]} {
  12097. lappend maps(:cmd)   -default [lindex $lbut $defb]
  12098. lappend maps(tkMBox) -default [lindex $lbut $defb]
  12099. }
  12100.  
  12101. if {![info exists dialogArgs(-cancel)]} {
  12102. lappend maps(:cmd) -cancel $canb
  12103. }
  12104.  
  12105. if {![info exists dialogArgs(-title)]} {
  12106. set frame [frame $path -class MessageDlg]
  12107. set title [option get $frame "${icon}Title" MessageDlg]
  12108. destroy $frame
  12109. if {![string length $title]} {
  12110. set title "Message"
  12111. }
  12112. lappend maps(:cmd) -title $title
  12113. lappend maps(tkMBox) -title $title
  12114. }
  12115.  
  12116. set name [Widget::getoption $dialog -name]
  12117. if {[string length $name]} { set native 0 }
  12118.  
  12119. if {!$native} {
  12120. if {!$user && !$width} { set width 12 }
  12121.  
  12122. set image ""
  12123. if {![string equal $icon "none"]} {
  12124. set image [BWidget::Icon dialog$icon]
  12125. }
  12126.  
  12127. eval [list Dialog::create $path] $maps(:cmd)  [list -image $image -modal local -side bottom -anchor c]
  12128. wm resizable $path 0 0
  12129.  
  12130. bind $path <Key-Left>  [list MessageDlg::_key_traversal $path left]
  12131. bind $path <Key-Right> [list MessageDlg::_key_traversal $path right]
  12132.  
  12133. foreach but $lbut {
  12134. Dialog::add $path -text $but -name $but -width $width
  12135. }
  12136.  
  12137. set frame [Dialog::getframe $path]
  12138.  
  12139. eval [list label $frame.msg] $maps(.frame.msg)  -relief flat -bd 0 -highlightthickness 0 -wraplength 800
  12140.  
  12141. pack $frame.msg -fill both -expand 1 -padx {5 10} -pady {5 0}
  12142.  
  12143. if {[string length $name]} {
  12144. set msg "Don't ask me again"
  12145. set varName [Widget::widgetVar $dialog dontAskAgain]
  12146. if {[BWidget::using ttk]} {
  12147. ttk::checkbutton $path.check -text $msg -variable $varName
  12148. } else {
  12149. checkbutton $path.check -text $msg -variable $varName
  12150. }
  12151.  
  12152. pack $path.check -anchor w -side bottom -pady {0 2}
  12153.  
  12154. bind $path.bbox <Map> [list pack configure $path.bbox -pady 5]
  12155. }
  12156.  
  12157. set res [Dialog::draw $path]
  12158. if {!$user} { set res [lindex $lbut $res] }
  12159.  
  12160. destroy $path
  12161. } else {
  12162. array set tkMBoxArgs $maps(tkMBox)
  12163.  
  12164. if {![string equal $icon "none"]} {
  12165. set tkMBoxArgs(-icon) $icon
  12166. }
  12167.  
  12168. if {[info exists tkMBoxArgs(-parent)]
  12169. && ![winfo exists $tkMBoxArgs(-parent)]} {
  12170. unset tkMBoxArgs(-parent)
  12171. }
  12172.  
  12173. set tkMBoxArgs(-type) $type
  12174. set res [eval tk_messageBox [array get tkMBoxArgs]]
  12175. }
  12176.  
  12177. if {[string length $name]} {
  12178. upvar #0 $varName var
  12179. if {$var} { set dialogs($name) $res }
  12180. }
  12181.  
  12182. Widget::destroy $dialog
  12183.  
  12184. return $res
  12185. }
  12186.  
  12187.  
  12188. proc MessageDlg::_key_traversal { path dir } {
  12189. set but [focus -lastfor $path]
  12190. if {$but eq $path} {
  12191. set def [ButtonBox::index $path.bbox default]
  12192. set but [ButtonBox::index $path.bbox $def]
  12193. ButtonBox::configure $path.bbox -default -1
  12194. }
  12195.  
  12196. set idx [ButtonBox::index $path.bbox $but]
  12197. set max [ButtonBox::index $path.bbox end]
  12198.  
  12199. if {$dir eq "left"} { incr idx -1 }
  12200. if {$dir eq "right"} { incr idx 1 }
  12201.  
  12202. if {$idx < 0} { set idx $max }
  12203. if {$idx > $max} { set idx 0 }
  12204.  
  12205. focus [ButtonBox::buttons $path.bbox $idx]
  12206. }
  12207.  
  12208.  
  12209. namespace eval Wizard {
  12210. Widget::define Wizard wizard ButtonBox Separator
  12211.  
  12212. namespace eval Step {
  12213. Widget::declare Wizard::Step {
  12214. {-background      Color2     ""       0  }
  12215. {-type            String     "step"   1  }
  12216. {-data            String     ""       0  }
  12217. {-title           String     ""       0  }
  12218. {-default         String     "next"   0  }
  12219.  
  12220. {-text1           String     ""       0  }
  12221. {-text2           String     ""       0  }
  12222. {-text3           String     ""       0  }
  12223. {-text4           String     ""       0  }
  12224. {-text5           String     ""       0  }
  12225.  
  12226. {-icon            String     ""       0  }
  12227. {-image           String     ""       0  }
  12228.  
  12229. {-bitmap          String     ""       0  }
  12230. {-iconbitmap      String     ""       0  }
  12231.  
  12232. {-createstep      Boolean2    ""      1  }
  12233. {-appendorder     Boolean    "1"      0  }
  12234.  
  12235. {-nexttext        String     ""       0  }
  12236. {-backtext        String     ""       0  }
  12237. {-helptext        String     ""       0  }
  12238. {-canceltext      String     ""       0  }
  12239. {-finishtext      String     ""       0  }
  12240. {-separatortext   String     ""       0  }
  12241.  
  12242. {-separator       Boolean2   ""       0  }
  12243.  
  12244. {-command         String     ""       0  }
  12245.  
  12246. {-createcommand   String     ""       0  }
  12247. {-raisecommand    String     ""       0  }
  12248. {-nextcommand     String     ""       0  }
  12249. {-backcommand     String     ""       0  }
  12250. {-helpcommand     String     ""       0  }
  12251. {-cancelcommand   String     ""       0  }
  12252. {-finishcommand   String     ""       0  }
  12253.  
  12254. {-compoundraise   Boolean    "1"      0  }
  12255. {-compoundcreate  Boolean    "1"      0  }
  12256.  
  12257. {-bg              Synonym    -background }
  12258. }
  12259. }
  12260.  
  12261. namespace eval Branch {
  12262. Widget::declare Wizard::Branch {
  12263. {-type            String     "branch" 1  }
  12264. {-command         String     ""       0  }
  12265. {-action          Enum       "merge"  0  {merge terminate} }
  12266. }
  12267. }
  12268.  
  12269. namespace eval Widget {
  12270. Widget::declare Wizard::Widget {
  12271. {-type            String     "widget" 1  }
  12272. {-step            String     ""       1  }
  12273. {-widget          String     ""       1  }
  12274. }
  12275. }
  12276.  
  12277. namespace eval layout {}
  12278.  
  12279. Widget::tkinclude Wizard frame :cmd  include    { -background -foreground -cursor }
  12280.  
  12281. Widget::declare Wizard {
  12282. {-type            Enum       "dialog" 1 {dialog frame} }
  12283. {-width           TkResource "475"    0 frame}
  12284. {-height          TkResource "350"    0 frame}
  12285. {-relief          TkResource "flat"   0 frame}
  12286. {-borderwidth     TkResource "0"      0 frame}
  12287. {-background      Color      "SystemButtonFace" 0}
  12288. {-foreground      String     "black"  0      }
  12289. {-title           String     "Wizard" 0      }
  12290. {-createstep      Boolean    "0"      0      }
  12291.  
  12292. {-autobuttons     Boolean    "1"      0      }
  12293. {-helpbutton      Boolean    "0"      1      }
  12294. {-finishbutton    Boolean    "0"      1      }
  12295. {-resizable       String     "0 0"    0      }
  12296. {-separator       Boolean    "1"      1      }
  12297. {-parent          String     "."      1      }
  12298. {-transient       Boolean    "1"      1      }
  12299. {-place           Enum       "center" 1
  12300. {none center left right above below} }
  12301.  
  12302. {-icon            String     ""       0      }
  12303. {-image           String     ""       0      }
  12304.  
  12305. {-bitmap          String     ""       0      }
  12306. {-iconbitmap      String     ""       0      }
  12307.  
  12308. {-raisecommand    String     ""       0      }
  12309. {-createcommand   String     ""       0      }
  12310.  
  12311. {-buttonwidth     Int        "12"     0      }
  12312. {-nexttext        String     "Next >" 0      }
  12313. {-backtext        String     "< Back" 0      }
  12314. {-helptext        String     "Help"   0      }
  12315. {-canceltext      String     "Cancel" 0      }
  12316. {-finishtext      String     "Finish" 0      }
  12317. {-separatortext   String     ""       0      }
  12318.  
  12319. {-fg              Synonym    -foreground     }
  12320. {-bg              Synonym    -background     }
  12321. {-bd              Synonym    -borderwidth    }
  12322. }
  12323.  
  12324. image create photo Wizard::none
  12325.  
  12326. Widget::addmap Wizard "" :cmd { -background {} -relief {} -borderwidth {} }
  12327.  
  12328. bind Wizard <Destroy> [list Wizard::_destroy %W]
  12329. }
  12330.  
  12331.  
  12332. proc Wizard::create { path args } {
  12333. Widget::initArgs Wizard $args maps
  12334.  
  12335. Widget::initFromODB Wizard $path $maps(Wizard)
  12336.  
  12337. Widget::getVariable $path data
  12338. Widget::getVariable $path branches
  12339.  
  12340. array set data {
  12341. steps   ""
  12342. buttons ""
  12343. order   ""
  12344. current ""
  12345. }
  12346.  
  12347. array set branches {
  12348. root    ""
  12349. }
  12350.  
  12351. set frame $path
  12352.  
  12353. set type [Widget::getoption $path -type]
  12354.  
  12355. if {[string equal $type "dialog"]} {
  12356. set top $path
  12357. eval [list toplevel $path -bg $::BWidget::colors(SystemButtonFace)]  $maps(:cmd) -class Wizard
  12358. wm withdraw   $path
  12359. update idletasks
  12360. wm protocol   $path WM_DELETE_WINDOW [list $path cancel 1]
  12361. if {[Widget::getoption $path -transient]} {
  12362. wm transient  $path [Widget::getoption $path -parent]
  12363. }
  12364. eval wm resizable $path [Widget::getoption $path -resizable]
  12365.  
  12366. set width  [Widget::cget $path -width]
  12367. set height [Widget::cget $path -height]
  12368. wm geometry $top ${width}x${height}
  12369.  
  12370. bind $path <Escape>         [list $path cancel]
  12371. bind $path <<WizardFinish>> [list destroy $path]
  12372. bind $path <<WizardCancel>> [list destroy $path]
  12373. } else {
  12374. set top [winfo toplevel $path]
  12375. eval [list frame $path] $maps(:cmd) -class Wizard
  12376. }
  12377.  
  12378. wm title $top [Widget::getoption $path -title]
  12379.  
  12380. grid rowconfigure    $top 0 -weight 1
  12381. grid columnconfigure $top 0 -weight 1
  12382.  
  12383. frame $path.steps
  12384. grid  $path.steps -row 0 -column 0 -sticky news
  12385.  
  12386. grid rowconfigure    $path.steps 0 -weight 1
  12387. grid columnconfigure $path.steps 0 -weight 1
  12388.  
  12389. widget $path set steps -widget $path.steps
  12390.  
  12391. if {[Widget::getoption $path -separator]} {
  12392. frame $path.separator
  12393. grid  $path.separator -row 1 -column 0 -sticky ew -pady [list 5 0]
  12394.  
  12395. grid columnconfigure $path.separator 1 -weight 1
  12396.  
  12397. label $path.separator.l -bd 0 -pady 0 -state disabled  -text [Widget::getoption $path -separatortext]
  12398. grid  $path.separator.l -row 0 -column 0 -sticky sw -padx 2
  12399.  
  12400. Separator $path.separator.s -orient horizontal
  12401. grid $path.separator.s -row 0 -column 1 -sticky sew  -padx [list 0 5] -pady 4
  12402.  
  12403. widget $path set separator      -widget $path.separator.s
  12404. widget $path set separatortext  -widget $path.separator.l
  12405. widget $path set separatorframe -widget $path.separator
  12406. }
  12407.  
  12408. ButtonBox $path.buttons -spacing 2 -homogeneous 1
  12409. grid $path.buttons -row 2 -column 0 -sticky e -padx 5 -pady {10 5}
  12410.  
  12411. widget $path set buttons -widget $path.buttons
  12412.  
  12413. Wizard::insert $path button end back -text "< Back"  -command [list $path back 1]  -width [Widget::getoption $path -buttonwidth]
  12414. Wizard::insert $path button end next -text "Next >"  -command [list $path next 1]
  12415. if {[Widget::getoption $path -finishbutton]} {
  12416. Wizard::insert $path button end finish -text "Finish"  -command [list $path finish 1]
  12417. }
  12418. Wizard::insert $path button end cancel -text "Cancel"  -command [list $path cancel 1] -spacing 10
  12419.  
  12420. if {[Widget::getoption $path -helpbutton]} {
  12421. Wizard::insert $path button 0 help -text "Help"  -command [list $path help 1] -spacing 10
  12422. }
  12423.  
  12424. return [Widget::create Wizard $path]
  12425. }
  12426.  
  12427.  
  12428. proc Wizard::configure { path args } {
  12429. set res [Widget::configure $path $args]
  12430.  
  12431. if {[Widget::hasChanged $path -title title]} {
  12432. wm title [winfo toplevel $path] $title
  12433. }
  12434.  
  12435. if {[Widget::hasChanged $path -resizable resize]} {
  12436. eval wm resizable [winfo toplevel $path] $resize
  12437. }
  12438.  
  12439. if {[Widget::getoption $path -separator]
  12440. && [Widget::hasChanged $path -separatortext text]} {
  12441. set text [Wizard::getoption $path [Wizard::raise $path] -separatortext]
  12442. Wizard::itemconfigure $path separatortext -text $text
  12443. }
  12444.  
  12445.  
  12446. if {[Widget::anyChangedX $path -width -height]} {
  12447. set type   [Widget::getoption $path -type]
  12448. set width  [Widget::cget $path -width]
  12449. set height [Widget::cget $path -height]
  12450.  
  12451. if {[string equal $type "dialog"]} {
  12452. wm geometry $path ${width}x${height}
  12453. } else {
  12454. $path:cmd configure -width $width -height $height
  12455. }
  12456. }
  12457.  
  12458. return $res
  12459. }
  12460.  
  12461.  
  12462. proc Wizard::cget { path option } {
  12463. return [Widget::cget $path $option]
  12464. }
  12465.  
  12466.  
  12467. proc Wizard::itemcget { path item option } {
  12468. Widget::getVariable $path items
  12469. Widget::getVariable $path steps
  12470. Widget::getVariable $path buttons
  12471. Widget::getVariable $path widgets
  12472.  
  12473. if {[Wizard::_is_step $path $item]} {
  12474. return [Widget::cget $items($item) $option]
  12475. }
  12476.  
  12477. if {[Wizard::_is_branch $path $item]} {
  12478. return [Widget::cget $items($item) $option]
  12479. }
  12480.  
  12481. if {[Wizard::_is_button $path $item]} {
  12482. return [$path.buttons itemcget $items($item) $option]
  12483. }
  12484.  
  12485. if {[Wizard::_is_widget $path $item]} {
  12486. return [eval [$path widget get $item] cget $option]
  12487. }
  12488.  
  12489. return -code error "item \"$item\" does not exist"
  12490. }
  12491.  
  12492.  
  12493. proc Wizard::itemconfigure { path item args } {
  12494. Widget::getVariable $path items
  12495. Widget::getVariable $path steps
  12496. Widget::getVariable $path buttons
  12497.  
  12498. if {[Wizard::_is_step $path $item]} {
  12499. set res [Widget::configure $items($item) $args]
  12500.  
  12501. if {$item eq [Wizard::step $path current]} {
  12502. if {[Widget::hasChanged $items($item) -title title]} {
  12503. set title [Wizard::getoption $path $item -title]
  12504. wm title [winfo toplevel $path] $title
  12505. }
  12506.  
  12507. if {[Widget::getoption $path -separator]
  12508. && [Widget::hasChanged $items($item) -separator separator]} {
  12509. if {[Wizard::getoption $path $item -separator]} {
  12510. grid $path.separator.s
  12511. } else {
  12512. grid remove $path.separator.s
  12513. }
  12514. }
  12515.  
  12516. if {[Widget::getoption $path -separator]
  12517. && [Widget::hasChanged $items($item) -separatortext text]} {
  12518. set text [Wizard::getoption $path $item -separatortext]
  12519. Wizard::itemconfigure $path separatortext -text $text
  12520. }
  12521.  
  12522. set x [list -nexttext -backtext -canceltext -helptext -finishtext]
  12523. if {[eval [list Widget::anyChangedX $path] $x]} {
  12524. Wizard::adjustbuttons $path
  12525. }
  12526. }
  12527.  
  12528. return $res
  12529. }
  12530.  
  12531. if {[Wizard::_is_branch $path $item]} {
  12532. return [Widget::configure $items($item) $args]
  12533. }
  12534.  
  12535. if {[Wizard::_is_button $path $item]} {
  12536. return [eval $path.buttons itemconfigure [list $items($item)] $args]
  12537. }
  12538.  
  12539. if {[Wizard::_is_widget $path $item]} {
  12540. return [eval [Wizard::widget $path get $item] configure $args]
  12541. }
  12542.  
  12543. return -code error "item \"$item\" does not exist"
  12544. }
  12545.  
  12546.  
  12547. proc Wizard::show { path } {
  12548. wm deiconify [winfo toplevel $path]
  12549. }
  12550.  
  12551.  
  12552. proc Wizard::hide { path } {
  12553. wm withdraw [winfo toplevel $path]
  12554. }
  12555.  
  12556.  
  12557. proc Wizard::invoke { path button } {
  12558. Widget::getVariable $path buttons
  12559. if {![info exists buttons($button)]} {
  12560. return -code error "button \"$button\" does not exist"
  12561. }
  12562. [Wizard::widget $path get $button] invoke
  12563. }
  12564.  
  12565.  
  12566. proc Wizard::insert { path type idx args } {
  12567. switch -- $type {
  12568. "button" {
  12569. set node [lindex $args 0]
  12570. set node [Widget::nextIndex $path $node]
  12571. set args [lreplace $args 0 0 $node]
  12572. }
  12573.  
  12574. "step" - "branch" {
  12575. set node   [lindex $args 1]
  12576. set branch [lindex $args 0]
  12577. set node   [Widget::nextIndex $path $node]
  12578. set args   [lreplace $args 1 1 $node]
  12579.  
  12580. if {![Wizard::_is_branch $path $branch]} {
  12581. return -code error "branch \"$branch\" does not exist"
  12582. }
  12583. }
  12584.  
  12585. default {
  12586. set types [list button branch step]
  12587. set err [BWidget::badOptionString option $type $types]
  12588. return -code error $err
  12589. }
  12590. }
  12591.  
  12592. if {[Wizard::exists $path $node]} {
  12593. return -code error "item \"$node\" already exists"
  12594. }
  12595.  
  12596. eval _insert_$type $path $idx $args
  12597.  
  12598. return $node
  12599. }
  12600.  
  12601.  
  12602. proc Wizard::delete { path args } {
  12603. Widget::getVariable $path data
  12604. Widget::getVariable $path items
  12605. Widget::getVariable $path steps
  12606. Widget::getVariable $path buttons
  12607. Widget::getVariable $path widgets
  12608. Widget::getVariable $path branches
  12609.  
  12610. set step [Wizard::step $path current]
  12611. foreach item $args {
  12612. set item [Wizard::step $path $item]
  12613. if {![string length $item]} { continue }
  12614.  
  12615. if {[Wizard::_is_step $path $item]} {
  12616.  
  12617. set branch [Wizard::branch $path $item]
  12618. set x [lsearch -exact $branches($branch) $item]
  12619. set branches($branch) [lreplace $branches($branch) $x $x]
  12620.  
  12621. destroy $widgets($item)
  12622.  
  12623. Widget::destroy $items($item) 0
  12624.  
  12625. unset steps($item)
  12626. unset data($item,branch)
  12627. unset items($item)
  12628. unset widgets($item)
  12629.  
  12630. if {[info exists data($item,realized)]} {
  12631. unset data($item,realized)
  12632. }
  12633.  
  12634. if {$item eq $step} { set data(current) "" }
  12635. }
  12636.  
  12637. if {[Wizard::_is_branch $path $item]} {
  12638.  
  12639. set branch [Wizard::branch $path $item]
  12640. set x [lsearch -exact $branches($branch) $item]
  12641. set branches($branch) [lreplace $branches($branch) $x $x]
  12642.  
  12643. Widget::destroy $items($item) 0
  12644.  
  12645. unset branches($item)
  12646. unset data($item,branch)
  12647. unset items($item)
  12648. }
  12649.  
  12650. if {[info exists buttons($item)]} {
  12651.  
  12652. set x [$path.buttons index $widgets($item)]
  12653. $path.buttons delete $x
  12654.  
  12655. unset items($item)
  12656. unset buttons($item)
  12657. unset widgets($item)
  12658. }
  12659. }
  12660. }
  12661.  
  12662.  
  12663. proc Wizard::back { path {generateEvent 0} {executeCommand 1} } {
  12664. Widget::getVariable $path data
  12665. Widget::getVariable $path items
  12666.  
  12667. set step [Wizard::raise $path]
  12668.  
  12669. if {$executeCommand && [string length $step]} {
  12670. set cmd [Widget::getoption $items($step) -backcommand]
  12671. if {![_eval_command $path $cmd]} { return }
  12672. }
  12673.  
  12674. if {$step ne [Wizard::raise $path]} { return }
  12675.  
  12676. set idx [lsearch -exact $data(order) $step]
  12677. if {$idx < 0} {
  12678. set item [lindex $data(order) end]
  12679. } else {
  12680. set item [lindex $data(order) [expr {$idx - 1}]]
  12681. set data(order) [lreplace $data(order) $idx end]
  12682. }
  12683.  
  12684. Wizard::raise $path $item $generateEvent
  12685.  
  12686. if {$generateEvent} { event generate $path <<WizardBack>> }
  12687.  
  12688. return $item
  12689. }
  12690.  
  12691.  
  12692. proc Wizard::next { path {generateEvent 0} {executeCommand 1} } {
  12693. Widget::getVariable $path data
  12694. Widget::getVariable $path items
  12695.  
  12696. set step [Wizard::raise $path]
  12697.  
  12698. if {$executeCommand && [string length $step]} {
  12699. set cmd [Widget::getoption $items($step) -nextcommand]
  12700. if {![_eval_command $path $cmd]} { return }
  12701. }
  12702.  
  12703. if {$step ne [Wizard::raise $path]} { return }
  12704.  
  12705. set item [Wizard::step $path next]
  12706. if {![string length $item]} { return }
  12707.  
  12708. if {[Widget::getoption $items($item) -appendorder]} {
  12709. lappend data(order) $item
  12710. }
  12711.  
  12712. Wizard::raise $path $item $generateEvent
  12713.  
  12714. if {$generateEvent} { event generate $path <<WizardNext>> }
  12715.  
  12716. return $item
  12717. }
  12718.  
  12719.  
  12720. proc Wizard::cancel { path {generateEvent 0} {executeCommand 1} } {
  12721. Widget::getVariable $path items
  12722.  
  12723. set step [Wizard::raise $path]
  12724.  
  12725. if {$executeCommand && [string length $step]} {
  12726. set cmd [Widget::getoption $items($step) -cancelcommand]
  12727. if {![_eval_command $path $cmd]} { return }
  12728. }
  12729.  
  12730. if {$generateEvent} { event generate $path <<WizardCancel>> }
  12731. }
  12732.  
  12733.  
  12734. proc Wizard::finish { path {generateEvent 0} {executeCommand 1} } {
  12735. Widget::getVariable $path items
  12736.  
  12737. set step [Wizard::raise $path]
  12738.  
  12739. if {$executeCommand && [string length $step]} {
  12740. set cmd [Widget::getoption $items($step) -finishcommand]
  12741. if {![_eval_command $path $cmd]} { return }
  12742. }
  12743.  
  12744. if {$generateEvent} { event generate $path <<WizardFinish>> }
  12745. }
  12746.  
  12747.  
  12748. proc Wizard::help { path {generateEvent 0} {executeCommand 1} } {
  12749. Widget::getVariable $path items
  12750.  
  12751. set step [Wizard::raise $path]
  12752.  
  12753. if {$executeCommand && [string length $step]} {
  12754. set cmd [Widget::getoption $items($step) -helpcommand]
  12755. if {![_eval_command $path $cmd]} { return }
  12756. }
  12757.  
  12758. if {$generateEvent} { event generate $path <<WizardHelp>> }
  12759. }
  12760.  
  12761.  
  12762. proc Wizard::order { path args } {
  12763. Widget::getVariable $path data
  12764. if {[llength $args] > 1} {
  12765. set err [BWidget::wrongNumArgsString "$path order ?neworder?"]
  12766. return -code error $err
  12767. }
  12768. if {[llength $args]} { set data(order) [lindex $args 0] }
  12769. return $data(order)
  12770. }
  12771.  
  12772.  
  12773. proc Wizard::step { path node {start ""} {traverse 1} } {
  12774. Widget::getVariable $path data
  12775. Widget::getVariable $path items
  12776. Widget::getVariable $path branches
  12777.  
  12778. if {[string length $start] && ![info exists items($start)]} {
  12779. return -code error "item \"$start\" does not exist"
  12780. }
  12781.  
  12782. switch -- $node {
  12783. "current" {
  12784. set item [Wizard::raise $path]
  12785. }
  12786.  
  12787. "end" - "last" {
  12788. set item [Wizard::step $path next]
  12789. while {[string length $item]} {
  12790. set last $item
  12791. set item [Wizard::step $path next $item]
  12792. }
  12793. set item $last
  12794. }
  12795.  
  12796. "back" - "previous" {
  12797. if {![string length $start]} { set start [Wizard::raise $path] }
  12798.  
  12799. set idx [lsearch -exact $data(order) $start]
  12800. if {$idx < 0} {
  12801. set item [lindex $data(order) end]
  12802. } else {
  12803. incr idx -1
  12804. if {$idx < 0} { return }
  12805. set item [lindex $data(order) $idx]
  12806. }
  12807. }
  12808.  
  12809. "next" {
  12810. if {[string length $start]} {
  12811. set step $start
  12812. } else {
  12813. set step [Wizard::raise $path]
  12814. }
  12815.  
  12816. set branch [Wizard::branch $path $step]
  12817. if {$traverse && [Wizard::_is_branch $path $step]} {
  12818. if {[Wizard::traverse $path $step]} {
  12819. set branch $step
  12820. }
  12821. }
  12822.  
  12823. set idx [expr {[lsearch -exact $branches($branch) $step] + 1}]
  12824.  
  12825. if {$idx >= [llength $branches($branch)]} {
  12826. if {$branch eq "root"
  12827. || [Widget::getoption $items($branch) -action]
  12828. eq "terminate"} {
  12829. return
  12830. }
  12831.  
  12832. set item [Wizard::step $path next $branch 0]
  12833. } else {
  12834. set item [lindex $branches($branch) $idx]
  12835.  
  12836. if {[Wizard::_is_branch $path $item]} {
  12837. if {$traverse} {
  12838. set item [Wizard::step $path next $item]
  12839. }
  12840. } else {
  12841. if {![Wizard::traverse $path $item]} {
  12842. set item [Wizard::step $path next $item]
  12843. }
  12844. }
  12845. }
  12846. }
  12847.  
  12848. default {
  12849. set item ""
  12850.  
  12851. if {[Wizard::_is_branch $path $node]} {
  12852. return [Wizard::step $path next $node]
  12853. }
  12854.  
  12855. if {[Wizard::_is_step $path $node]} { set item $node }
  12856. }
  12857. }
  12858.  
  12859. return $item
  12860. }
  12861.  
  12862.  
  12863. proc Wizard::nodes { path branch {first ""} {last ""} } {
  12864. Widget::getVariable $path data
  12865. Widget::getVariable $path branches
  12866. if {![string length $first]} { return $branches($branch) }
  12867. if {![string length $last]}  { return [lindex $branches($branch) $first] }
  12868. return [lrange $branches($branch) $first $last]
  12869. }
  12870.  
  12871.  
  12872. proc Wizard::index { path item } {
  12873. Widget::getVariable $path branches
  12874. set item   [$path step $item]
  12875. set branch [$path branch $item]
  12876. return [lsearch -exact $branches($branch) $item]
  12877. }
  12878.  
  12879.  
  12880. proc Wizard::raise { path {item ""} {generateEvent 0} } {
  12881. Widget::getVariable $path data
  12882. Widget::getVariable $path items
  12883.  
  12884. set steps   $path.steps
  12885. set buttons $path.buttons
  12886.  
  12887. if {[string equal $item ""]} { return $data(current) }
  12888.  
  12889. set x $item
  12890. set curr $data(current)
  12891. set item [Wizard::step $path $item]
  12892.  
  12893. if {![string length $item]} {
  12894. return -code error "step \"$x\" does not exist"
  12895. }
  12896.  
  12897. if {[string equal $item $data(current)]} { return }
  12898.  
  12899. Wizard::createstep $path $item
  12900.  
  12901. if {[Widget::getoption $items($item) -compoundraise]} {
  12902. set cmd [Widget::getoption $path -raisecommand]
  12903. Wizard::_eval_command $path $cmd $item
  12904. }
  12905.  
  12906. if {$data(current) ne $curr} { return $data(current) }
  12907.  
  12908. set cmd [Widget::getoption $items($item) -raisecommand]
  12909. Wizard::_eval_command $path $cmd $item
  12910.  
  12911. if {$data(current) ne $curr} { return $data(current) }
  12912.  
  12913. wm title [winfo toplevel $path] [Wizard::getoption $path $item -title]
  12914.  
  12915. if {[Wizard::getoption $path $item -separator]} {
  12916. grid $path.separator.s
  12917. set text [Wizard::getoption $path $item -separatortext]
  12918. $path itemconfigure separatortext -text $text
  12919. } else {
  12920. grid remove $path.separator.s
  12921. $path itemconfigure separatortext -text ""
  12922. }
  12923.  
  12924. set default [Widget::getoption $items($item) -default]
  12925. set button  [lsearch -exact $data(buttons) $default]
  12926. $buttons setfocus $button
  12927.  
  12928. if {[string length $data(current)]} {
  12929. grid remove $steps.f$data(current)
  12930. }
  12931.  
  12932. set data(current) $item
  12933.  
  12934. grid $steps.f$data(current) -row 0 -column 0 -sticky news
  12935.  
  12936. set back [Wizard::step $path back]
  12937. set next [Wizard::step $path next]
  12938.  
  12939. if {[Widget::getoption $path -autobuttons]} { Wizard::adjustbuttons $path }
  12940.  
  12941. if {$generateEvent} {
  12942. if {$back eq ""} { event generate $path <<WizardFirstStep>> }
  12943. if {$next eq ""} { event generate $path <<WizardLastStep>> }
  12944. event generate $path <<WizardStep>>
  12945. }
  12946.  
  12947. return $item
  12948. }
  12949.  
  12950.  
  12951. proc Wizard::adjustbuttons { path } {
  12952. Widget::getVariable $path items
  12953.  
  12954. set item [Wizard::step $path current]
  12955. if {[string equal $item ""]} { return }
  12956.  
  12957. set back [Wizard::step $path back]
  12958. set next [Wizard::step $path next]
  12959.  
  12960. foreach x [list back next cancel] {
  12961. set text [Wizard::getoption $path $item -${x}text]
  12962. $path itemconfigure $x -text $text -state normal
  12963. }
  12964.  
  12965. if {[Widget::getoption $path -helpbutton]} {
  12966. set text [Wizard::getoption $path $item -helptext]
  12967. $path itemconfigure help -text $text
  12968. }
  12969.  
  12970. if {[Widget::getoption $path -finishbutton]} {
  12971. set text [Wizard::getoption $path $item -finishtext]
  12972. $path itemconfigure finish -text $text -state disabled
  12973. }
  12974.  
  12975. if {[string equal $back ""]} {
  12976. $path itemconfigure back -state disabled
  12977. }
  12978.  
  12979. if {[string equal $next ""]} {
  12980. if {[Widget::getoption $path -finishbutton]} {
  12981. $path itemconfigure next   -state disabled
  12982. $path itemconfigure finish -state normal
  12983. } else {
  12984. set text [Wizard::getoption $path $item -finishtext]
  12985. $path itemconfigure next -text $text -command [list $path finish 1]
  12986. }
  12987. $path itemconfigure back   -state disabled
  12988. $path itemconfigure cancel -state disabled
  12989. } else {
  12990. set text [Wizard::getoption $path $item -nexttext]
  12991. $path itemconfigure next -text $text -command [list $path next 1]
  12992. }
  12993. }
  12994.  
  12995.  
  12996. proc Wizard::widget { path command args } {
  12997. return [eval [list Wizard::widgets $path $command] $args]
  12998. }
  12999.  
  13000.  
  13001. proc Wizard::widgets { path command args } {
  13002. Widget::getVariable $path items
  13003. Widget::getVariable $path widgets
  13004. Widget::getVariable $path stepWidgets
  13005.  
  13006. switch -- $command {
  13007. "set" {
  13008. set node [lindex $args 0]
  13009. if {[string equal $node ""]} {
  13010. set str "$path widget set <name> ?option ..?"
  13011. set err [BWidget::wrongNumArgsString $str]
  13012. return -code error $err
  13013. }
  13014. set args [lreplace $args 0 0]
  13015. set item $path.#widget#$node
  13016.  
  13017. Widget::init Wizard::Widget $item $args
  13018. set step   [Widget::getoption $item -step]
  13019. set widget [Widget::getoption $item -widget]
  13020. set items($node) $item
  13021. if {[string equal $step ""]} {
  13022. set widgets($node) $widget
  13023. } else {
  13024. set stepWidgets($step,$node) $widget
  13025. }
  13026. return $widget
  13027. }
  13028.  
  13029. "get" {
  13030. set widget [lindex $args 0]
  13031. if {[string equal [string index $widget 0] "-"]} {
  13032. set widget ""
  13033. } else {
  13034. set args [lreplace $args 0 0]
  13035. }
  13036.  
  13037. array set map  [list Wizard::Widget {}]
  13038. array set map  [Widget::parseArgs Wizard::Widget $args]
  13039. array set data $map(Wizard::Widget)
  13040.  
  13041. if {[info exists data(-step)]} {
  13042. set step $data(-step)
  13043.  
  13044. if {[string equal $widget ""]} {
  13045. set list [list]
  13046. foreach name [array names stepWidgets $step,*] {
  13047. set x [lrange [split $name ,] 1 end]
  13048. lappend list [eval join $x ,]
  13049. }
  13050. return $list
  13051. }
  13052. } else {
  13053. if {[string equal $widget ""]} {
  13054. return [array names widgets]
  13055. }
  13056.  
  13057. set step [$path step current]
  13058. }
  13059.  
  13060. if {[info exists stepWidgets($step,$widget)]} {
  13061. return $stepWidgets($step,$widget)
  13062. }
  13063.  
  13064. if {![info exists widgets($widget)]} {
  13065. return -code error "item \"$widget\" does not exist"
  13066. }
  13067.  
  13068. return $widgets($widget)
  13069. }
  13070.  
  13071. default {
  13072. set err [BWidget::badOptionString option $command [list get set]]
  13073. return -code error $err
  13074. }
  13075. }
  13076. }
  13077.  
  13078.  
  13079. proc Wizard::variable { path step option } {
  13080. set item [step $path $step]
  13081. if {[string equal $item ""]} {
  13082. return -code error "item \"$step\" does not exist"
  13083. }
  13084. set item $path.$item
  13085. return [Widget::varForOption $item $option]
  13086. }
  13087.  
  13088.  
  13089. proc Wizard::branch { path {node "current"} } {
  13090. Widget::getVariable $path data
  13091.  
  13092. if {[_is_branch $path $node]} { return $data($node,branch) }
  13093.  
  13094. set node [$path step $node]
  13095. if {[string equal $node ""]} { return "root" }
  13096. if {[info exists data($node,branch)]} { return $data($node,branch) }
  13097. return -code error "item \"$node\" does not exist"
  13098. }
  13099.  
  13100.  
  13101. proc Wizard::traverse { path node } {
  13102. Widget::getVariable $path items
  13103.  
  13104. if {$node eq "root"} { return 1 }
  13105.  
  13106. if {![info exists items($node)]} {
  13107. return -code error "node \"$node\" does not exist"
  13108. }
  13109.  
  13110. set cmd [Widget::getoption $items($node) -command]
  13111. return [_eval_command $path $cmd]
  13112. }
  13113.  
  13114.  
  13115. proc Wizard::exists { path item } {
  13116. Widget::getVariable $path items
  13117. return [info exists items($item)]
  13118. }
  13119.  
  13120.  
  13121. proc Wizard::createstep { path item {delete 0} } {
  13122. Widget::getVariable $path data
  13123. Widget::getVariable $path items
  13124.  
  13125. set item [Wizard::step $path $item]
  13126.  
  13127. if {![Wizard::_is_step $path $item]} { return }
  13128.  
  13129. if {$delete} {
  13130. if {[winfo exists $path.f$item]} {
  13131. destroy $path.f$item
  13132. }
  13133. if {[info exists data($item,realized)]} {
  13134. unset data($item,realized)
  13135. }
  13136. }
  13137.  
  13138. if {![info exists data($item,realized)]} {
  13139. set data($item,realized) 1
  13140.  
  13141. if {[Widget::getoption $items($item) -compoundcreate]} {
  13142. set cmd [Widget::getoption $path -createcommand]
  13143. _eval_command $path $cmd $item
  13144. }
  13145.  
  13146. set cmd [Widget::getoption $items($item) -createcommand]
  13147. _eval_command $path $cmd $item
  13148. }
  13149.  
  13150. return $item
  13151. }
  13152.  
  13153.  
  13154. proc Wizard::getoption { path item option } {
  13155. Widget::getVariable $path items
  13156. set step [Wizard::step $path $item]
  13157. if {![string length $step]} {
  13158. return -code error "item \"$item\" does not exist"
  13159. }
  13160. return [Widget::cgetOption $option "" $items($step) $path]
  13161. }
  13162.  
  13163.  
  13164. proc Wizard::reorder { path parent nodes } {
  13165. Widget::getVariable $path branches
  13166. set branches($parent) $nodes
  13167. if {[Widget::getoption $path -autobuttons]} { Wizard::adjustbuttons $path }
  13168. }
  13169.  
  13170.  
  13171. proc Wizard::_insert_button { path idx node args } {
  13172. Widget::getVariable $path data
  13173. Widget::getVariable $path items
  13174. Widget::getVariable $path buttons
  13175. Widget::getVariable $path widgets
  13176.  
  13177. set buttons($node) 1
  13178. set widgets($node) [eval $path.buttons insert $idx $args]
  13179. set item   [string map [list $path.buttons.b {}] $widgets($node)]
  13180. set items($node) $item
  13181. return $widgets($node)
  13182. }
  13183.  
  13184.  
  13185. proc Wizard::_insert_step { path idx branch node args } {
  13186. Widget::getVariable $path data
  13187. Widget::getVariable $path steps
  13188. Widget::getVariable $path items
  13189. Widget::getVariable $path widgets
  13190. Widget::getVariable $path branches
  13191.  
  13192. set steps($node) 1
  13193. set data($node,branch) $branch
  13194. if {$idx eq "end"} {
  13195. lappend branches($branch) $node
  13196. } else {
  13197. set branches($branch) [linsert $branches($branch) $idx $node]
  13198. }
  13199.  
  13200. Widget::init Wizard::Step $path.$node $args
  13201.  
  13202. set items($node) $path.$node
  13203. set bg [Wizard::getoption $path $node -background]
  13204.  
  13205. set widgets($node) [frame $path.steps.f$node -bg $bg]
  13206.  
  13207. if {[getoption $path $node -createstep]} { Wizard::createstep $path $node }
  13208.  
  13209. if {[Widget::getoption $path -autobuttons]} { Wizard::adjustbuttons $path }
  13210.  
  13211. return $widgets($node)
  13212. }
  13213.  
  13214.  
  13215. proc Wizard::_insert_branch { path idx branch node args } {
  13216. Widget::getVariable $path data
  13217. Widget::getVariable $path items
  13218. Widget::getVariable $path branches
  13219.  
  13220. set branches($node)    [list]
  13221. set data($node,branch) $branch
  13222. if {$idx eq "end"} {
  13223. lappend branches($branch) $node
  13224. } else {
  13225. set branches($branch) [linsert $branches($branch) $idx $node]
  13226. }
  13227.  
  13228. Widget::init Wizard::Branch $path.$node $args
  13229.  
  13230. if {[Widget::getoption $path -autobuttons]} { Wizard::adjustbuttons $path }
  13231.  
  13232. set items($node) $path.$node
  13233.  
  13234. return $items($node)
  13235. }
  13236.  
  13237.  
  13238. proc Wizard::_is_step { path node } {
  13239. Widget::getVariable $path steps
  13240. return [info exists steps($node)]
  13241. }
  13242.  
  13243.  
  13244. proc Wizard::_is_branch { path node } {
  13245. Widget::getVariable $path branches
  13246. return [info exists branches($node)]
  13247. }
  13248.  
  13249.  
  13250. proc Wizard::_is_button { path node } {
  13251. Widget::getVariable $path buttons
  13252. return [info exists buttons($node)]
  13253. }
  13254.  
  13255.  
  13256. proc Wizard::_is_widget { path node } {
  13257. Widget::getVariable $path widgets
  13258. return [info exists widgets($node)]
  13259. }
  13260.  
  13261.  
  13262. proc Wizard::_eval_command { path command {step ""} } {
  13263. if {![string length $command]} { return 1 }
  13264.  
  13265. if {![string length $step]} { set step [Wizard::raise $path] }
  13266.  
  13267. set map [list %W $path %S $step]
  13268.  
  13269. if {![Wizard::_is_branch $path $step]} {
  13270. if {[string match "*%B*" $command]} {
  13271. lappend map %B [Wizard::branch $path $step]
  13272. }
  13273.  
  13274. if {[string match "*%n*" $command]} {
  13275. lappend map %n [Wizard::step $path next $step]
  13276. }
  13277.  
  13278. if {[string match "*%b*" $command]} {
  13279. lappend map %b [Wizard::step $path back $step]
  13280. }
  13281. }
  13282.  
  13283. return [uplevel #0 [string map $map $command]]
  13284. }
  13285.  
  13286.  
  13287. proc Wizard::_destroy { path } {
  13288. Widget::getVariable $path items
  13289.  
  13290. foreach item [array names items] {
  13291. Widget::destroy $items($item) 0
  13292. }
  13293.  
  13294. Widget::destroy $path
  13295. }
  13296.  
  13297.  
  13298. proc SimpleWizard { path args } {
  13299. option add *WizLayoutSimple*Label.padX                5    interactive
  13300. option add *WizLayoutSimple*Label.anchor              nw   interactive
  13301. option add *WizLayoutSimple*Label.justify             left interactive
  13302. option add *WizLayoutSimple*Label.borderWidth         0    interactive
  13303. option add *WizLayoutSimple*Label.highlightThickness  0    interactive
  13304.  
  13305. set args [linsert $args 0 -createstep 1]
  13306. lappend args -createcommand [list Wizard::layout::simple %W %S]
  13307.  
  13308. return [eval [list Wizard $path] $args]
  13309. }
  13310.  
  13311.  
  13312. proc ClassicWizard { path args } {
  13313. option add *WizLayoutClassic*Label.padX                5    interactive
  13314. option add *WizLayoutClassic*Label.anchor              nw   interactive
  13315. option add *WizLayoutClassic*Label.justify             left interactive
  13316. option add *WizLayoutClassic*Label.borderWidth         0    interactive
  13317. option add *WizLayoutClassic*Label.highlightThickness  0    interactive
  13318.  
  13319. set args [linsert $args 0 -createstep 1]
  13320. lappend args -createcommand [list Wizard::layout::classic %W %S]
  13321.  
  13322. return [eval [list Wizard $path] $args]
  13323. }
  13324.  
  13325.  
  13326. proc Wizard::layout::simple { wizard step } {
  13327. set frame [$wizard widget get $step]
  13328.  
  13329. set layout [$wizard widget set layout -widget $frame.layout -step $step]
  13330.  
  13331. foreach w [list titleframe pretext posttext clientArea] {
  13332. set $w [$wizard widget set $w -widget $layout.$w -step $step]
  13333. }
  13334.  
  13335. foreach w [list title subtitle icon] {
  13336. set $w [$wizard widget set $w -widget $titleframe.$w -step $step]
  13337. }
  13338.  
  13339. frame $layout -class WizLayoutSimple
  13340.  
  13341. pack $layout -expand 1 -fill both
  13342.  
  13343. frame $clientArea -bd 8 -relief flat
  13344.  
  13345. Separator $layout.sep1 -relief groove -orient horizontal
  13346.  
  13347. frame $titleframe -bd 4 -relief flat -background white
  13348. label $title -background white -textvariable [$wizard variable $step -text1]
  13349. label $subtitle -height 2 -background white -padx 15 -width 40  -textvariable [$wizard variable $step -text2]
  13350.  
  13351. label $icon -borderwidth 0 -background white -anchor c
  13352. set iconImage [$wizard getoption $step -icon]
  13353. if {[string length $iconImage]} { $icon configure -image $iconImage }
  13354.  
  13355. set labelfont [font actual [$title cget -font]]
  13356. $title configure -font [concat $labelfont -weight bold]
  13357.  
  13358. grid $title    -in $titleframe -row 0 -column 0 -sticky nsew
  13359. grid $subtitle -in $titleframe -row 1 -column 0 -sticky nsew
  13360. grid $icon     -in $titleframe -row 0 -column 1 -rowspan 2 -padx 8
  13361. grid columnconfigure $titleframe 0 -weight 1
  13362. grid columnconfigure $titleframe 1 -weight 0
  13363.  
  13364. label $pretext  -textvariable [$wizard variable $step -text3]
  13365. label $posttext -textvariable [$wizard variable $step -text4]
  13366.  
  13367. foreach widget [list title subtitle pretext posttext] {
  13368. bind [set $widget] <Configure> {
  13369. after idle {after idle {%W configure -wraplength [expr {%w -10}]}}
  13370. }
  13371. }
  13372.  
  13373. grid $titleframe  -row 0 -column 0 -sticky nsew -padx 0
  13374. grid $layout.sep1 -row 1 -sticky ew
  13375. grid $pretext     -row 2 -sticky nsew -padx 8 -pady 8
  13376. grid $clientArea  -row 3 -sticky nsew -padx 8 -pady 8
  13377. grid $posttext    -row 4 -sticky nsew -padx 8 -pady 8
  13378.  
  13379. grid columnconfigure $layout 0 -weight 1
  13380. grid rowconfigure    $layout 0 -weight 0
  13381. grid rowconfigure    $layout 1 -weight 0
  13382. grid rowconfigure    $layout 2 -weight 0
  13383. grid rowconfigure    $layout 3 -weight 1
  13384. grid rowconfigure    $layout 4 -weight 0
  13385. }
  13386.  
  13387. proc Wizard::layout::classic { wizard step } {
  13388. set frame [$wizard widget get $step]
  13389.  
  13390. set layout [$wizard widget set layout -widget $frame.layout -step $step]
  13391. foreach w [list title subtitle icon pretext posttext clientArea] {
  13392. set $w [$wizard widget set $w -widget $layout.$w -step $step]
  13393. }
  13394.  
  13395. frame $layout -class WizLayoutClassic
  13396.  
  13397. pack $layout -expand 1 -fill both
  13398.  
  13399. frame $clientArea -bd 8 -relief flat
  13400.  
  13401. Separator $layout.sep1 -relief groove -orient vertical
  13402.  
  13403. label $title    -textvariable [$wizard variable $step -text1]
  13404. label $subtitle -textvariable [$wizard variable $step -text2] -height 2
  13405.  
  13406. array set labelfont [font actual [$title cget -font]]
  13407. incr labelfont(-size) 6
  13408. set  labelfont(-weight) bold
  13409. $title configure -font [array get labelfont]
  13410.  
  13411. label $pretext  -textvariable [$wizard variable $step -text3]
  13412. label $posttext -textvariable [$wizard variable $step -text4]
  13413.  
  13414. foreach widget [list title subtitle pretext posttext] {
  13415. bind [set $widget] <Configure> {
  13416. after idle {after idle {%W configure -wraplength [expr {%w -10}]}}
  13417. }
  13418. }
  13419.  
  13420. label $icon -borderwidth 1 -relief sunken -background white  -anchor c -width 96 -image Wizard::none
  13421. set iconImage [$wizard getoption $step -icon]
  13422. if {[string length $iconImage]} { $icon configure -image $iconImage }
  13423.  
  13424. grid $icon       -row 0 -column 0 -sticky nsew -padx 8 -pady 8 -rowspan 5
  13425. grid $title      -row 0 -column 1 -sticky ew   -padx 8 -pady 8
  13426. grid $subtitle   -row 1 -column 1 -sticky ew   -padx 8 -pady 8
  13427. grid $pretext    -row 2 -column 1 -sticky ew   -padx 8
  13428. grid $clientArea -row 3 -column 1 -sticky nsew -padx 8
  13429. grid $posttext   -row 4 -column 1 -sticky ew   -padx 8 -pady 24
  13430.  
  13431. grid columnconfigure $layout 0 -weight 0
  13432. grid columnconfigure $layout 1 -weight 1
  13433.  
  13434. grid rowconfigure    $layout 0 -weight 0
  13435. grid rowconfigure    $layout 1 -weight 0
  13436. grid rowconfigure    $layout 2 -weight 0
  13437. grid rowconfigure    $layout 3 -weight 1
  13438. grid rowconfigure    $layout 4 -weight 0
  13439. }
  13440.  
  13441.  
  13442.  
  13443. proc ThemeSetup {} {
  13444. if {$::tcl_platform(platform) ne "windows"} {
  13445. option add *font                TkTextFont
  13446. option add *background          [style default . -background]
  13447. option add *selectForeground    [style default . -selectforeground]
  13448. option add *selectBackground    [style default . -selectbackground]
  13449.  
  13450. option add *Listbox.background  white
  13451.  
  13452. option add *Entry.background    white
  13453. option add *Entry.borderWidth   1
  13454.  
  13455. option add *Text.background     white
  13456. }
  13457. }
  13458.  
  13459. ThemeSetup
  13460. ThemeInit
  13461. ::InstallJammer::HideMainWindow
  13462. }
  13463. } setup.tcl {proc ::InstallJammer::InitSetup {} {
  13464. FileGroup ::FileGroups
  13465. Component ::Components
  13466. SetupType ::SetupTypes
  13467. FileGroup ::BC9DDC29-8CDB-4C1E-A9F2-F002B44B6E20 -setup Install -type filegroup -active Yes -platforms {Linux-x86 Windows} -name {Program Files} -parent FileGroups
  13468. Component ::25A03054-7BF5-4B4A-A5E8-98C36C53A0F9 -setup Install -type component -active Yes -platforms {Linux-x86 Windows} -name {Default Component} -parent Components
  13469. SetupType ::DC9387EF-9B53-4C8B-AF18-5FDDAD31BD0E -setup Install -type setuptype -active Yes -platforms {Linux-x86 Windows} -name Typical -parent SetupTypes
  13470. SetupType ::4A354C44-1D80-4EFC-991B-1550F2A9E791 -setup Install -type setuptype -active Yes -platforms {Linux-x86 Windows} -name Custom -parent SetupTypes
  13471.  
  13472. }} common.tcl ##\ \$Id\$\n##\n##\ Copyright\ (C)\ 2002\ \ Damon\ Courtney\n##\ \n##\ This\ program\ is\ free\ software\;\ you\ can\ redistribute\ it\ and/or\n##\ modify\ it\ under\ the\ terms\ of\ the\ GNU\ General\ Public\ License\n##\ as\ published\ by\ the\ Free\ Software\ Foundation\;\ either\ version\ 2\n##\ of\ the\ License,\ or\ (at\ your\ option)\ any\ later\ version.\n##\ \n##\ This\ program\ is\ distributed\ in\ the\ hope\ that\ it\ will\ be\ useful,\n##\ but\ WITHOUT\ ANY\ WARRANTY\;\ without\ even\ the\ implied\ warranty\ of\n##\ MERCHANTABILITY\ or\ FITNESS\ FOR\ A\ PARTICULAR\ PURPOSE.\ \ See\ the\n##\ GNU\ General\ Public\ License\ for\ more\ details.\n##\ \n##\ You\ should\ have\ received\ a\ copy\ of\ the\ GNU\ General\ Public\ License\n##\ along\ with\ this\ program\;\ if\ not,\ write\ to\ the\n##\ \ \ \ \ Free\ Software\ Foundation,\ Inc.\n##\ \ \ \ \ 51\ Franklin\ Street,\ Fifth\ Floor\n##\ \ \ \ \ Boston,\ MA\ \ 02110-1301,\ USA.\n##\n\nnamespace\ eval\ ::InstallJammer\ \{\}\n\nproc\ lempty\ \{list\}\ \{\n\ \ \ \ if\ \{\[catch\ \{expr\ \[llength\ \$list\]\ ==\ 0\}\ ret\]\}\ \{\ return\ 0\ \}\n\ \ \ \ return\ \$ret\n\}\n\nproc\ lassign\ \{\ list\ args\ \}\ \{\n\ \ \ \ foreach\ elem\ \$list\ varName\ \$args\ \{\n\ \ \ \ \tupvar\ 1\ \$varName\ var\n\tset\ var\ \$elem\n\ \ \ \ \}\n\}\n\nproc\ lremove\ \{\ list\ args\ \}\ \{\n\ \ \ \ foreach\ arg\ \$args\ \{\n\tset\ x\ \[lsearch\ -exact\ \$list\ \$arg\]\n\tset\ list\ \[lreplace\ \$list\ \$x\ \$x\]\n\ \ \ \ \}\n\ \ \ \ return\ \$list\n\}\n\nproc\ lreverse\ \{\ list\ \}\ \{\n\ \ \ \ set\ new\ \[list\]\n\ \ \ \ set\ len\ \[llength\ \$list\]\n\ \ \ \ for\ \{set\ i\ \[expr\ \$len\ -\ 1\]\}\ \{\$i\ >=\ 0\}\ \{incr\ i\ -1\}\ \{\n\tlappend\ new\ \[lindex\ \$list\ \$i\]\n\ \ \ \ \}\n\ \ \ \ return\ \$new\n\}\n\nproc\ lassign_array\ \{list\ arrayName\ args\}\ \{\n\ \ \ \ upvar\ 1\ \$arrayName\ array\n\ \ \ \ foreach\ elem\ \$list\ var\ \$args\ \{\n\tset\ array(\$var)\ \$elem\n\ \ \ \ \}\n\}\n\nproc\ incr0\ \{\ varName\ \{n\ 1\}\ \}\ \{\n\ \ \ \ upvar\ 1\ \$varName\ var\n\ \ \ \ if\ \{!\[info\ exists\ var\]\}\ \{\ set\ var\ 0\ \}\n\ \ \ \ incr\ var\ \$n\n\}\n\nproc\ iincr\ \{\ varName\ \{n\ 1\}\ \}\ \{\n\ \ \ \ upvar\ 1\ \$varName\ var\n\ \ \ \ if\ \{!\[info\ exists\ var\]\}\ \{\ set\ var\ 0\ \}\n\ \ \ \ set\ var\ \[expr\ \{\$var\ +\ \$n\}\]\n\}\n\nproc\ recursive_glob\ \{dir\ pattern\}\ \{\n\ \ \ \ set\ files\ \[glob\ -nocomplain\ -type\ f\ -dir\ \$dir\ \$pattern\]\n\ \ \ \ foreach\ dir\ \[glob\ -nocomplain\ -type\ d\ -dir\ \$dir\ *\]\ \{\n\ \ \ \ \ \ \ \ eval\ lappend\ files\ \[recursive_glob\ \$dir\ \$pattern\]\n\ \ \ \ \}\n\ \ \ \ return\ \$files\n\}\n\nproc\ noop\ \{args\}\ \{\}\n\nproc\ read_file\ \{\ file\ args\ \}\ \{\n\ \ \ \ set\ fp\ \[open\ \$file\]\n\ \ \ \ eval\ \[list\ fconfigure\ \$fp\]\ -encoding\ utf-8\ \$args\n\ \ \ \ set\ x\ \[read\ \$fp\]\n\ \ \ \ close\ \$fp\n\ \ \ \ return\ \$x\n\}\n\nproc\ debug\ \{\ message\ \{id\ \"\"\}\ \}\ \{\n\ \ \ \ set\ time\ \[clock\ format\ \[clock\ seconds\]\ -format\ \"%m/%d/%Y\ %H:%M:%S%p\"\]\n\ \ \ \ set\ string\ \"\$time\ -\ \$message\"\n\n\ \ \ \ if\ \{\[set\ x\ \[::InstallJammer::SubstText\ \$message\]\]\ ne\ \$message\}\ \{\n\ \ \ \ \ \ \ \ append\ string\ \"\\n\$time\ -\ **\ \$x\"\n\ \ \ \ \}\n\n\ \ \ \ if\ \{\$id\ ne\ \"\"\ &&\ \[\$id\ get\ Comment\ comment\]\ &&\ \$comment\ ne\ \"\"\}\ \{\n\ \ \ \ \ \ \ \ append\ string\ \"\\n\$time\ -\ #\ \$comment\"\n\ \ \ \ \ \ \ \ if\ \{\[set\ x\ \[::InstallJammer::SubstText\ \$comment\]\]\ ne\ \$comment\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ append\ string\ \"\\n\$time\ -\ **\ \$x\"\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ if\ \{!\[info\ exists\ ::InstallJammer\]\}\ \{\n\ \ \ \ \ \ \ \ if\ \{\[info\ exists\ ::debug\]\ &&\ \$::debug\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ puts\ \ stderr\ \$string\n\ \ \ \ \ \ \ \ \ \ \ \ flush\ stderr\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ if\ \{\$::conf(debugging)\}\ \{\n\ \ \ \ \ \ \ \ if\ \{!\[info\ exists\ ::debugfp\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ ::debugfp\ \[open\ \[::InstallJammer::TmpDir\ debug.log\]\ w\]\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ puts\ \ \$::debugfp\ \$string\n\ \ \ \ \ \ \ \ flush\ \$::debugfp\n\ \ \ \ \}\n\}\n\}\n\nproc\ SafeSet\ \{\ varName\ value\ \}\ \{\n\ \ \ \ upvar\ 1\ \$varName\ var\n\ \ \ \ if\ \{!\[info\ exists\ var\]\}\ \{\ set\ var\ \$value\ \}\n\ \ \ \ return\ \$value\n\}\n\nproc\ SafeArraySet\ \{\ arrayName\ list\ \}\ \{\n\ \ \ \ upvar\ 1\ \$arrayName\ array\n\ \ \ \ foreach\ \{varName\ elem\}\ \$list\ \{\n\tif\ \{!\[info\ exists\ array(\$varName)\]\}\ \{\ set\ array(\$varName)\ \$elem\ \}\n\ \ \ \ \}\n\}\n\n\npackage\ require\ msgcat\n\n##\ We're\ going\ to\ redefine\ some\ of\ Tcl's\ msgcat\ commands\ in\ the\n##\ name\ of\ simplifying\ things.\nproc\ ::msgcat::mc\ \{\ src\ args\ \}\ \{\n\ \ \ \ foreach\ loc\ \[concat\ \[::msgcat::mcpreferences\]\ en\]\ \{\n\ \ \ \ \ \ \ \ if\ \{\[info\ exists\ ::msgcat::Msgs_\$\{loc\}(\$src)\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ dest\ \[set\ ::msgcat::Msgs_\$\{loc\}(\$src)\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{!\[llength\ \$args\]\}\ \{\ return\ \$dest\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ return\ \[uplevel\ 1\ \[linsert\ \$args\ 0\ ::format\ \$dest\]\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ if\ \{\[llength\ \$args\]\}\ \{\n\ \ \ \ \ \ \ \ return\ \[uplevel\ 1\ \[linsert\ \$args\ 0\ ::format\ \$src\]\]\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ return\ \$src\n\ \ \ \ \}\n\}\n\nproc\ ::msgcat::mcexists\ \{\ src\ \{locales\ \{\}\}\ \}\ \{\n\ \ \ \ if\ \{!\[llength\ \$locales\]\}\ \{\n\ \ \ \ \ \ \ \ set\ locales\ \[concat\ \[::msgcat::mcpreferences\]\ en\]\n\ \ \ \ \}\n\ \ \ \ foreach\ locale\ \$locales\ \{\n\ \ \ \ \ \ \ \ if\ \{\$locale\ eq\ \"None\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ upvar\ #0\ ::info\ msgs\n\ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ upvar\ #0\ ::msgcat::Msgs_\$\{locale\}\ msgs\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ if\ \{\[info\ exists\ msgs(\$src)\]\}\ \{\ return\ 1\ \}\n\ \ \ \ \}\n\ \ \ \ return\ 0\n\}\n\nproc\ ::msgcat::mcset\ \{\ locale\ src\ \{dest\ \"\"\}\ \}\ \{\n\ \ \ \ if\ \{\$locale\ eq\ \"None\"\}\ \{\n\ \ \ \ \ \ \ \ upvar\ #0\ ::info\ msgs\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ upvar\ #0\ ::msgcat::Msgs_\$\{locale\}\ msgs\n\ \ \ \ \}\n\n\ \ \ \ if\ \{\[llength\ \[info\ level\ 0\]\]\ ==\ 3\}\ \{\ set\ dest\ \$src\ \}\n\ \ \ \ set\ msgs(\$src)\ \$dest\n\}\n\nproc\ ::msgcat::mcunset\ \{\ locale\ src\ \}\ \{\n\ \ \ \ if\ \{\$locale\ eq\ \"None\"\}\ \{\n\ \ \ \ \ \ \ \ upvar\ #0\ ::info\ msgs\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ upvar\ #0\ ::msgcat::Msgs_\$\{locale\}\ msgs\n\ \ \ \ \}\n\n\ \ \ \ unset\ -nocomplain\ msgs(\$src)\n\}\n\nproc\ ::msgcat::mcmset\ \{\ locale\ pairs\ \}\ \{\n\ \ \ \ if\ \{\$locale\ eq\ \"None\"\}\ \{\n\ \ \ \ \ \ \ \ upvar\ #0\ ::info\ msgs\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ upvar\ #0\ ::msgcat::Msgs_\$\{locale\}\ msgs\n\ \ \ \ \}\n\n\ \ \ \ array\ set\ msgs\ \$pairs\n\}\n\nproc\ ::msgcat::mcgetall\ \{\ locale\ \}\ \{\n\ \ \ \ if\ \{\$locale\ eq\ \"None\"\}\ \{\n\ \ \ \ \ \ \ \ upvar\ #0\ ::info\ msgs\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ upvar\ #0\ ::msgcat::Msgs_\$\{locale\}\ msgs\n\ \ \ \ \}\n\n\ \ \ \ return\ \[array\ get\ msgs\]\n\}\n\nproc\ ::msgcat::mcget\ \{\ locale\ src\ args\ \}\ \{\n\ \ \ \ if\ \{\$locale\ eq\ \"None\"\}\ \{\n\ \ \ \ \ \ \ \ upvar\ #0\ ::info\ msgs\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ upvar\ #0\ ::msgcat::Msgs_\$\{locale\}\ msgs\n\ \ \ \ \}\n\n\ \ \ \ if\ \{\[info\ exists\ msgs(\$src)\]\}\ \{\n\ \ \ \ \ \ \ \ set\ dest\ \$msgs(\$src)\n\ \ \ \ \ \ \ \ if\ \{!\[llength\ \$args\]\}\ \{\ return\ \$dest\ \}\n\ \ \ \ \ \ \ \ return\ \[uplevel\ 1\ \[linsert\ \$args\ 0\ ::format\ \$dest\]\]\n\ \ \ \ \}\n\n\ \ \ \ if\ \{\[llength\ \$args\]\}\ \{\n\ \ \ \ \ \ \ \ return\ \[uplevel\ 1\ \[linsert\ \$args\ 0\ ::format\ \$src\]\]\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ return\ \$src\n\ \ \ \ \}\n\}\n\nproc\ ::msgcat::mcclear\ \{\ locale\ \}\ \{\n\ \ \ \ unset\ -nocomplain\ ::msgcat::Msgs_\$\{locale\}\n\}\n\nnamespace\ eval\ ::InstallJammer\ \{\}\nnamespace\ eval\ ::InstallJammer::actions\ \{\}\nnamespace\ eval\ ::InstallJammer::conditions\ \{\}\n\nproc\ ::InstallJammer::CommonInit\ \{\}\ \{\n\ \ \ \ global\ info\n\ \ \ \ global\ conf\n\n\ \ \ \ if\ \{\[info\ exists\ conf(commonInit)\]\}\ \{\ return\ \}\n\n\ \ \ \ set\ conf(windows)\ \[string\ equal\ \$::tcl_platform(platform)\ \"windows\"\]\n\n\ \ \ \ array\ set\ conf\ \{\n\tcommonInit\ \ \ 1\n\ \ \ \ \ \ \ \ debugging\ \ \ \ 0\n\n\ \ \ \ \ \ \ \ ParentWindow\ \"\"\n\n\tSubstDirVars\ \{\n\t\ \ \ \ CommonStartMenu\n\ \ \ \ \ \ \ \ \ \ \ \ Desktop\n\ \ \ \ \ \ \ \ \ \ \ \ FileBeingInstalled\n\t\ \ \ \ GnomeCommonStartMenu\n\t\ \ \ \ GnomeDesktop\n\t\ \ \ \ GnomeStartMenu\n\t\ \ \ \ Home\n\t\ \ \ \ InstallDir\n\t\ \ \ \ Installer\n\t\ \ \ \ InstallLogDirectory\n\t\ \ \ \ InstallSource\n\t\ \ \ \ KDECommonStartMenu\n\t\ \ \ \ KDEDesktop\n\t\ \ \ \ KDEStartMenu\n\ \ \ \ \ \ \ \ \ \ \ \ ProgramReadme\n\ \ \ \ \ \ \ \ \ \ \ \ ProgramLicense\n\t\ \ \ \ ProgramExecutable\n\t\ \ \ \ ProgramFolder\n\t\ \ \ \ Uninstaller\n\t\ \ \ \ UninstallDirectory\n\t\}\n\n\ \ \ \ \ \ \ \ VirtualTextMap\ \ \ \ \ \ \ \ \ \ \ \ \{\}\n\tVirtualTextRecursionLimit\ 10\n\ \ \ \ \}\n\n\ \ \ \ lappend\ conf(VirtualTextMap)\ \"\\\\\"\ \"\\\\\\\\\"\ \"\\\[\"\ \"\\\\\\\[\"\n\ \ \ \ lappend\ conf(VirtualTextMap)\ \"<%\"\ \{\[::InstallJammer::SubstVar\ \[list\ \}\n\ \ \ \ lappend\ conf(VirtualTextMap)\ \"%>\"\ \{\]\]\}\n\n\ \ \ \ if\ \{\[info\ exists\ ::installkit::root\]\}\ \{\n\ \ \ \ \ \ \ \ set\ conf(vfs)\ \$::installkit::root\n\ \ \ \ \}\n\ \ \ \ set\ conf(exe)\ \ \ \ \ \ \[info\ nameofexecutable\]\n\ \ \ \ set\ conf(script)\ \ \ \[info\ script\]\n\ \ \ \ set\ conf(threaded)\ \[info\ exists\ ::tcl_platform(threaded)\]\n\n\ \ \ \ if\ \{\$conf(windows)\}\ \{\n\ \ \ \ \ \ \ \ set\ info(Ext)\ .exe\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ set\ info(Ext)\ \"\"\n\ \ \ \ \}\n\n\ \ \ \ ::InstallJammer::InitializeMessageCatalogs\n\n\ \ \ \ if\ \{!\[info\ exists\ ::InstallJammer\]\}\ \{\n\ \ \ \ \ \ \ \ ##\ Setup\ common\ variables\ for\ an\ install\ or\ uninstall.\n\ \ \ \ \ \ \ \ array\ set\ info\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ Wizard\ \ \ \ \ \ \ \ \ \ \ .wizard\n\ \ \ \ \ \ \ \ \ \ \ \ WizardFirstStep\ \ 0\n\ \ \ \ \ \ \ \ \ \ \ \ WizardLastStep\ \ \ 0\n\t\ \ \ \ Errors\ \ \ \ \ \ \ \ \ \ \ \"\"\n\n\ \ \ \ \ \ \ \ \ \ \ \ SilentMode\ \ \ \ \ \ \ 0\n\ \ \ \ \ \ \ \ \ \ \ \ DefaultMode\ \ \ \ \ \ 0\n\ \ \ \ \ \ \ \ \ \ \ \ InstallMode\ \ \ \ \ \ \"Standard\"\n\n\ \ \ \ \ \ \ \ \ \ \ \ UserMovedBack\ \ \ \ 0\n\ \ \ \ \ \ \ \ \ \ \ \ UserMovedNext\ \ \ \ 0\n\n\ \ \ \ \ \ \ \ \ \ \ \ RunningInstaller\ \ \ 0\n\ \ \ \ \ \ \ \ \ \ \ \ RunningUninstaller\ 0\n\ \ \ \ \ \ \ \ \}\n\n\tSafeArraySet\ info\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ AllowLanguageSelection\ 1\n\ \ \ \ \ \ \ \ \ \ \ \ IncludeDebugging\ \ \ \ \ \ \ No\n\ \ \ \ \ \ \ \ \ \ \ \ Language\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ en\n\n\ \ \ \ \ \ \ \ \ \ \ \ SpaceRequiredText\ \ \"<%DiskSpace\ <%SpaceRequired%>%>\"\n\ \ \ \ \ \ \ \ \ \ \ \ SpaceAvailableText\ \"<%DiskSpace\ <%SpaceAvailable%>%>\"\n\t\}\n\n\ \ \ \ \ \ \ \ if\ \{\[info\ exists\ info(DefaultLanguage)\]\ &&\ \$info(RunningInstaller)\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ info(Language)\ \$info(DefaultLanguage)\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ variable\ languages\n\ \ \ \ \ \ \ \ variable\ languagecodes\n\ \ \ \ \ \ \ \ if\ \{\[info\ exists\ languages(\$info(Language))\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ info(Language)\ \$languages(\$info(Language))\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ set\ info(Username)\ \$::tcl_platform(user)\n\ \ \ \ \ \ \ \ if\ \{!\[catch\ \{\ exec\ whoami\ \}\ username\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ info(Username)\ \$username\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ set\ info(UserIsRoot)\ \[string\ equal\ \$info(Username)\ \"root\"\]\n\n\ \ \ \ \ \ \ \ ::InstallJammer::GetInstallInfoDir\n\n\t##\ Setup\ the\ virtual\ registry\ texts\ on\ Windows.\n\ \ \ \ \ \ \ \ if\ \{\$conf(windows)\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ info(Desktop)\ <%DESKTOP%>\n\n\ \ \ \ \ \ \ \ \ \ \ \ set\ root\ \"<%PROGRAMS%>\"\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$info(ProgramFolderAllUsers)\}\ \{\ set\ root\ \"<%COMMON_PROGRAMS%>\"\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ set\ info(ProgramFolder)\ \"\$root/<%ProgramFolderName%>\"\n\n\ \ \ \ \ \ \ \ \ \ \ \ SetupRegVirtualText\n\ \ \ \ \ \ \ \ \ \ \ \ ::InstallJammer::SetWindowsPlatform\n\ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ info(HasKDEDesktop)\ \ \ \[::InstallJammer::HasKDEDesktop\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ info(HasGnomeDesktop)\ \[::InstallJammer::HasGnomeDesktop\]\n\n\ \ \ \ \ \ \ \ \ \ \ \ switch\ --\ \[::InstallJammer::GetDesktopEnvironment\]\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \"KDE\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ info(Desktop)\ <%KDEDesktop%>\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \"Gnome\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ info(Desktop)\ <%GnomeDesktop%>\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ SafeArraySet\ info\ \{\n\ \ \ \ \ \ \ \ Date\ \ \ \ \ \ \ \ \ \ \ \ \"<%Date\ <%DateFormat%>%>\"\n\ \ \ \ \ \ \ \ DateFormat\ \ \ \ \ \ \"%Y%m%d\"\n\ \ \ \ \}\n\n\ \ \ \ set\ conf(mclocale)\ \[::msgcat::mcpreferences\]\n\n\ \ \ \ if\ \{\[info\ exists\ info(Language)\]\}\ \{\n\ \ \ \ \ \ \ \ ::msgcat::mclocale\ \$info(Language)\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ ::msgcat::mclocale\ en\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::InitializeMessageCatalogs\ \{\}\ \{\n\ \ \ \ global\ conf\n\ \ \ \ global\ info\n\n\ \ \ \ variable\ languages\n\ \ \ \ variable\ languagecodes\n\n\ \ \ \ if\ \{!\[array\ exists\ languagecodes\]\}\ \{\n\ \ \ \ \ \ \ \ array\ set\ languagecodes\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ de\ \ \ \ \ \ German\n\ \ \ \ \ \ \ \ \ \ \ \ en\ \ \ \ \ \ English\n\ \ \ \ \ \ \ \ \ \ \ \ es\ \ \ \ \ \ Spanish\n\ \ \ \ \ \ \ \ \ \ \ \ fr\ \ \ \ \ \ French\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ if\ \{\[info\ exists\ info(Languages)\]\}\ \{\n\ \ \ \ \ \ \ \ array\ set\ languagecodes\ \$info(Languages)\n\ \ \ \ \}\n\n\ \ \ \ foreach\ var\ \[array\ names\ languagecodes\]\ \{\n\ \ \ \ \ \ \ \ set\ languages(\$languagecodes(\$var))\ \$var\n\ \ \ \ \}\n\ \ \ \ set\ languages(None)\ None\n\n\ \ \ \ return\ \[lsort\ \[array\ names\ languagecodes\]\]\n\}\n\nproc\ ::InstallJammer::GetLanguageCodes\ \{\}\ \{\n\ \ \ \ variable\ languagecodes\n\ \ \ \ return\ \[lsort\ \[array\ names\ languagecodes\]\]\n\}\n\nproc\ ::InstallJammer::GetLanguages\ \{\ \{includeNone\ 0\}\ \}\ \{\n\ \ \ \ variable\ languages\n\ \ \ \ set\ list\ \[lremove\ \[lsort\ \[array\ names\ languages\]\]\ None\]\n\ \ \ \ if\ \{\$includeNone\}\ \{\ set\ list\ \[linsert\ \$list\ 0\ None\]\ \}\n\ \ \ \ return\ \$list\n\}\n\nproc\ ::InstallJammer::LoadTwapi\ \{\}\ \{\n\ \ \ \ global\ conf\n\n\ \ \ \ ##\ Check\ to\ see\ if\ the\ user\ included\ the\ TWAPI\ extension\n\ \ \ \ ##\ and\ that\ we're\ on\ Windows\ XP\ or\ higher.\ \ If\ so,\ require\n\ \ \ \ ##\ the\ extension\ to\ load\ the\ commands.\n\ \ \ \ if\ \{\$conf(windows)\n\ \ \ \ \ \ \ \ &&\ \$::tcl_platform(osVersion)\ >=\ 5.0\n\ \ \ \ \ \ \ \ &&\ \[info\ exists\ ::installkit::root\]\n\ \ \ \ \ \ \ \ &&\ \[llength\ \[package\ versions\ twapi\]\]\}\ \{\n\ \ \ \ \ \ \ \ ##\ Set\ a\ variable\ to\ trick\ TWAPI.\n\ \ \ \ \ \ \ \ namespace\ eval\ ::starkit\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ variable\ topdir\ \$::installkit::root\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ package\ require\ twapi\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::HideMainWindow\ \{\}\ \{\n\ \ \ \ global\ conf\n\ \ \ \ global\ info\n\n\ \ \ \ ##\ Hide\ the\ .\ window\ so\ no\ one\ will\ ever\ find\ it.\n\ \ \ \ wm\ title\ \ \ \ .\ \"\$info(AppName)\ Setup\"\n\ \ \ \ wm\ geometry\ .\ 0x0+-10000+-10000\n\ \ \ \ if\ \{!\$conf(windows)\ ||\ \$info(SilentMode)\}\ \{\ wm\ overrideredirect\ .\ 1\ \}\n\ \ \ \ if\ \{!\$info(SilentMode)\}\ \{\ wm\ deiconify\ .\ \}\n\}\n\nproc\ ::InstallJammer::NewStyle\ \{\ newStyle\ oldStyle\ args\ \}\ \{\n\ \ \ \ style\ layout\ \$newStyle\ \[style\ layout\ \$oldStyle\]\n\ \ \ \ eval\ \[list\ style\ configure\ \$newStyle\]\ \[style\ configure\ \$oldStyle\]\ \$args\n\ \ \ \ return\ \$newStyle\n\}\n\nproc\ ::InstallJammer::CreateDir\ \{\ dir\ \{log\ 1\}\ \}\ \{\n\ \ \ \ variable\ CreateDir\n\n\ \ \ \ if\ \{!\[info\ exists\ CreateDir(\$dir)\]\}\ \{\n\ \ \ \ \ \ \ \ set\ list\ \[file\ split\ \$dir\]\n\n\ \ \ \ \ \ \ \ for\ \{set\ i\ 0\}\ \{\$i\ <\ \[llength\ \$list\]\}\ \{incr\ i\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ dirlist\ \[lindex\ \$list\ \$i\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ dir\ \[eval\ file\ join\ \$dirlist\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{!\[info\ exists\ CreateDir(\$dir)\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ CreateDir(\$dir)\ 1\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{!\[file\ exists\ \$dir\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ file\ mkdir\ \$dir\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$log\}\ \{\ ::InstallJammer::LogDir\ \$dir\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ return\ \$dir\n\}\n\nproc\ ::InstallJammer::DirIsEmpty\ \{\ dir\ \}\ \{\n\ \ \ \ set\ list1\ \[glob\ -nocomplain\ -directory\ \$dir\ *\]\n\ \ \ \ set\ list2\ \[glob\ -nocomplain\ -directory\ \$dir\ -types\ hidden\ *\]\n\ \ \ \ set\ list\ \ \[lremove\ \[concat\ \$list1\ \$list2\]\ \$dir/.\ \$dir/..\]\n\ \ \ \ return\ \ \ \ \[lempty\ \$list\]\n\}\n\nproc\ ::InstallJammer::PlaceWindow\ \{\ id\ args\ \}\ \{\n\ \ \ \ set\ id\ \[::InstallJammer::ID\ \$id\]\n\ \ \ \ set\ anchor\ center\n\n\ \ \ \ if\ \{\[winfo\ exists\ \$id\]\}\ \{\n\ \ \ \ \ \ \ \ set\ target\ \$id\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ set\ target\ \[\$id\ window\]\n\ \ \ \ \ \ \ \ if\ \{!\[\$id\ get\ Anchor\ anchor\]\}\ \{\ set\ anchor\ center\ \}\n\ \ \ \ \}\n\n\ \ \ \ array\ set\ data\ \"\n\t-anchor\ \$anchor\n\t-width\ \ \[winfo\ reqwidth\ \ \$target\]\n\t-height\ \[winfo\ reqheight\ \$target\]\n\ \ \ \ \"\n\n\ \ \ \ array\ set\ data\ \$args\n\n\ \ \ \ set\ w\ \ \$data(-width)\n\ \ \ \ set\ h\ \ \$data(-height)\n\ \ \ \ set\ sw\ \[winfo\ screenwidth\ \$target\]\n\ \ \ \ set\ sh\ \[winfo\ screenheight\ \$target\]\n\ \ \ \ lassign\ \[wm\ maxsize\ .\]\ maxw\ maxh\n\ \ \ \ set\ anchor\ \$data(-anchor)\n\ \ \ \ switch\ --\ \$anchor\ \{\n\t\"center\"\ \{\n\t\ \ \ \ set\ x0\ \[expr\ (\$sw\ -\ \$w)\ /\ 2\ -\ \[winfo\ vrootx\ \$target\]\]\n\t\ \ \ \ set\ y0\ \[expr\ (\$sh\ -\ \$h)\ /\ 2\ -\ \[winfo\ vrooty\ \$target\]\]\n\t\}\n\n\t\"n\"\ \{\n\t\ \ \ \ set\ x0\ \[expr\ (\$sw\ -\ \$w)\ \ /\ 2\ -\ \[winfo\ vrootx\ \$target\]\]\n\t\ \ \ \ set\ y0\ 20\n\t\}\n\n\t\"ne\"\ \{\n\t\ \ \ \ set\ x0\ \[expr\ \$maxw\ -\ \$w\ -\ 40\]\n\t\ \ \ \ set\ y0\ 20\n\t\}\n\n\t\"e\"\ \{\n\t\ \ \ \ set\ x0\ \[expr\ \$maxw\ -\ \$w\ -\ 40\]\n\t\ \ \ \ set\ y0\ \[expr\ (\$sh\ -\ \$h)\ /\ 2\ -\ \[winfo\ vrooty\ \$target\]\]\n\t\}\n\n\t\"se\"\ \{\n\t\ \ \ \ set\ x0\ \[expr\ \$maxw\ -\ \$w\ -\ 40\]\n\t\ \ \ \ set\ y0\ \[expr\ \$maxh\ -\ \$h\ -\ 80\]\n\t\}\n\n\t\"s\"\ \{\n\t\ \ \ \ set\ x0\ \[expr\ (\$sw\ -\ \$w)\ \ /\ 2\ -\ \[winfo\ vrootx\ \$target\]\]\n\t\ \ \ \ set\ y0\ \[expr\ \$maxh\ -\ \$h\ -\ 80\]\n\t\}\n\n\t\"sw\"\ \{\n\t\ \ \ \ set\ x0\ 20\n\t\ \ \ \ set\ y0\ \[expr\ \$maxh\ -\ \$h\ -\ 80\]\n\t\}\n\n\t\"w\"\ \{\n\t\ \ \ \ set\ x0\ 20\n\t\ \ \ \ set\ y0\ \[expr\ (\$sh\ -\ \$h)\ /\ 2\ -\ \[winfo\ vrooty\ \$target\]\]\n\t\}\n\n\t\"nw\"\ \{\n\t\ \ \ \ set\ x0\ 20\n\t\ \ \ \ set\ y0\ 20\n\t\}\n\n\tdefault\ \{\n\t\ \ \ \ append\ msg\ \"bad\ anchor\ \\\"\$anchor\\\":\ must\ be\"\n\t\ \ \ \ append\ msg\ \"n,\ ne,\ e,\ se,\ s,\ sw,\ w,\ nw\ or\ center\"\n\t\ \ \ \ return\ -code\ error\ \$msg\n\t\}\n\ \ \ \ \}\n\n\ \ \ \ set\ x\ \"+\$x0\"\n\ \ \ \ set\ y\ \"+\$y0\"\n\ \ \ \ if\ \{\ \$x0+\$w\ >\ \$sw\ \}\ \{set\ x\ \"-0\"\;\ set\ x0\ \[expr\ \{\$sw-\$w\}\]\}\n\ \ \ \ if\ \{\ \$x0\ <\ 0\ \}\ \ \ \ \ \ \{set\ x\ \"+0\"\}\n\ \ \ \ if\ \{\ \$y0+\$h\ >\ \$sh\ \}\ \{set\ y\ \"-0\"\;\ set\ y0\ \[expr\ \{\$sh-\$h\}\]\}\n\ \ \ \ if\ \{\ \$y0\ <\ 0\ \}\ \ \ \ \ \ \{set\ y\ \"+0\"\}\n\n\ \ \ \ wm\ geometry\ \$target\ \$x\$y\n\ \ \ \ update\n\}\n\nproc\ ::InstallJammer::CenterWindow\ \{\ target\ \{w\ 473\}\ \{h\ 335\}\ \{lower\ 0\}\ \}\ \{\n\ \ \ \ set\ args\ \[list\ -width\ \$w\ -height\ \$h\]\n\ \ \ \ if\ \{\$lower\}\ \{\ lappend\ args\ -anchor\ s\ \}\n\ \ \ \ eval\ \[list\ PlaceWindow\ \$target\]\ \$args\n\}\n\nproc\ ::InstallJammer::ID\ \{\ alias\ \}\ \{\n\ \ \ \ variable\ ::InstallJammer::aliases\n\ \ \ \ if\ \{\[info\ exists\ aliases(\$alias)\]\}\ \{\ return\ \$aliases(\$alias)\ \}\n\ \ \ \ return\ \$alias\n\}\n\nproc\ ::InstallJammer::FindCommonPane\ \{\ pane\ \}\ \{\n\ \ \ \ foreach\ id\ \[Common\ children\]\ \{\n\ \ \ \ \ \ \ \ if\ \{\[string\ equal\ \[\$id\ component\]\ \$pane\]\}\ \{\ return\ \$id\ \}\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::FindObjByName\ \{\ name\ objects\ \}\ \{\n\ \ \ \ foreach\ object\ \$objects\ \{\n\ \ \ \ \ \ \ \ if\ \{\[string\ equal\ \[\$object\ name\]\ \$name\]\}\ \{\ return\ \$object\ \}\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::GetPaneProc\ \{\ id\ prefix\ \}\ \{\n\ \ \ \ set\ proc\ \$prefix.\$id\n\ \ \ \ if\ \{!\[::InstallJammer::CommandExists\ \$proc\]\}\ \{\n\ \ \ \ \tset\ proc\ \$prefix.\[\$id\ component\]\n\ \ \ \ \}\n\ \ \ \ if\ \{\[::InstallJammer::CommandExists\ \$proc\]\}\ \ \{\ return\ \$proc\ \}\n\}\n\nproc\ ::InstallJammer::ExecuteActions\ \{\ id\ args\ \}\ \{\n\ \ \ \ array\ set\ _args\ \{\n\ \ \ \ \ \ \ \ -when\ \ \ \ \ \ \ \"\"\n\ \ \ \ \ \ \ \ -type\ \ \ \ \ \ \ \"\"\n\ \ \ \ \ \ \ \ -parent\ \ \ \ \ \"\"\n\ \ \ \ \ \ \ \ -conditions\ 1\n\ \ \ \ \}\n\ \ \ \ array\ set\ _args\ \$args\n\n\ \ \ \ set\ id\ \[::InstallJammer::ID\ \$id\]\n\n\ \ \ \ if\ \{!\[::InstallJammer::ObjExists\ \$id\]\}\ \{\ return\ \}\n\n\ \ \ \ if\ \{\[catch\ \{\ \$id\ title\ \}\ title\]\}\ \{\ set\ title\ \$id\ \}\n\n\ \ \ \ if\ \{\[\$id\ is\ action\]\}\ \{\n\ \ \ \ \ \ \ \ set\ idlist\ \[list\ \$id\]\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ set\ idlist\ \[\$id\ children\]\n\ \ \ \ \}\n\n\ \ \ \ if\ \{!\[llength\ \$idlist\]\}\ \{\ return\ \}\n\n\ \ \ \ set\ msg\ \"Executing\ actions\ \$id\ -\ \$title\"\n\ \ \ \ if\ \{\$_args(-when)\ ne\ \"\"\}\ \{\ append\ msg\ \"\ -\ \$_args(-when)\"\ \}\n\ \ \ \ debug\ \$msg\n\n\ \ \ \ set\ res\ \ 1\n\ \ \ \ set\ tempObjects\ \[list\]\n\ \ \ \ foreach\ childid\ \$idlist\ \{\n\ \ \ \ \ \ \ \ set\ err\ \ 0\n\ \ \ \ \ \ \ \ set\ res\ \ 1\n\ \ \ \ \ \ \ \ set\ obj\ \ \$childid\n\ \ \ \ \ \ \ \ set\ type\ \[\$obj\ component\]\n\n\ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$_args(-type)\]\ &&\ \$type\ ne\ \$_args(-type)\}\ \{continue\}\n\n\ \ \ \ \ \ \ \ ##\ If\ we\ have\ a\ parent,\ it\ means\ that\ we're\ an\ ExecuteAction\n\ \ \ \ \ \ \ \ ##\ action\ that\ is\ calling\ another\ action,\ which\ can\ also\ be\n\ \ \ \ \ \ \ \ ##\ an\ action\ group.\ \ We\ want\ the\ action\ we're\ executing\n\ \ \ \ \ \ \ \ ##\ to\ have\ the\ attributes\ of\ the\ parent\ action,\ so\ we\ create\n\ \ \ \ \ \ \ \ ##\ a\ temporary\ object\ that\ inherits\ the\ attributes\ of\ the\n\ \ \ \ \ \ \ \ ##\ parent\ and\ execute\ that\ in\ place\ of\ the\ original\ object.\n\n\ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$_args(-parent)\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ obj\ \[::InstallJammer::CreateTempAction\ \$_args(-parent)\ \$childid\]\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ tempObjects\ \$obj\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \$obj\ get\ IgnoreErrors\ \ ignoreErrors\n\ \ \ \ \ \ \ \ \$obj\ get\ ExecuteAction\ when\n\n\ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$_args(-when)\]\n\ \ \ \ \ \ \ \ \ \ \ \ &&\ !\[string\ equal\ -nocase\ \$_args(-when)\ \$when\]\}\ \{\ continue\ \}\n\n\ \ \ \ \ \ \ \ if\ \{\$_args(-conditions)\ &&\ !\[\$obj\ checkConditions\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ debug\ \"Skipping\ action\ \$childid\ -\ \[\$childid\ title\]\\\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\ conditions\ failed\"\n\ \ \ \ \ \ \ \ \ \ \ \ continue\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ debug\ \"Executing\ action\ \$childid\ -\ \[\$childid\ title\]\"\ \$childid\n\n\ \ \ \ \ \ \ \ set\ err\ \[catch\ \{::InstallJammer::actions::\$type\ \$obj\}\ res\]\n\ \ \ \ \ \ \ \ set\ errorInfo\ \$::errorInfo\n\n\ \ \ \ \ \ \ \ if\ \{\$err\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ ##\ An\ error\ occurred\ processing\ the\ action.\ \ If\ the\ user\n\ \ \ \ \ \ \ \ \ \ \ \ ##\ has\ opted\ to\ ignore\ errors,\ we\ just\ continue\ on.\n\ \ \ \ \ \ \ \ \ \ \ \ ##\ Otherwise,\ we\ return\ the\ error\ which\ will\ fail\ the\ install.\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$ignoreErrors\}\ \{\ continue\ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ set\ msg\ \"An\ error\ has\ occurred\ during\ installation\\n\\t\$errorInfo\"\n\ \ \ \ \ \ \ \ \ \ \ \ return\ -code\ error\ \$msg\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ if\ \{\[llength\ \$tempObjects\]\}\ \{\n\ \ \ \ eval\ itcl::delete\ object\ \$tempObjects\n\}\n\}\n\nproc\ ::InstallJammer::CreateTempAction\ \{\ id\ child\ \}\ \{\n\ \ \ \ set\ obj\ \[InstallComponent\ ::#auto\ -temp\ 1\ -parent\ \[\$id\ parent\]\ \\\n\ \ \ \ \ \ \ \ -setup\ \[\$id\ setup\]\ -type\ action\ -id\ \$child\ -name\ \[\$child\ name\]\ \\\n\ \ \ \ \ \ \ \ -component\ \[\$child\ component\]\ -conditions\ \[\$child\ conditions\]\]\n\n\ \ \ \ return\ \$obj\n\}\n\n##\ Uses\ the\ wizard's\ -backcommand\ option.\nproc\ ::InstallJammer::BackCommand\ \{\ wizard\ id\ \}\ \{\n\ \ \ \ global\ info\n\n\ \ \ \ set\ when\ \"Before\ Previous\ Pane\ is\ Displayed\"\n\n\ \ \ \ if\ \{!\[\$id\ checkConditions\ \$when\]\}\ \{\ return\ 0\ \}\n\n\ \ \ \ ::InstallJammer::ExecuteActions\ \$id\ -when\ \$when\n\n\ \ \ \ set\ info(UserMovedBack)\ 1\n\ \ \ \ set\ info(UserMovedNext)\ 0\n\n\ \ \ \ return\ 1\n\}\n\n##\ This\ command\ is\ executed\ when\ the\ user\ hits\ next\ but\ before\n##\ the\ next\ pane\ is\ displayed.\n##\ Uses\ the\ wizard's\ -nextcommand\ option.\nproc\ ::InstallJammer::NextCommand\ \{\ wizard\ id\ \}\ \{\n\ \ \ \ global\ info\n\n\ \ \ \ set\ when\ \"Before\ Next\ Pane\ is\ Displayed\"\n\n\ \ \ \ if\ \{!\[\$id\ checkConditions\ \$when\]\}\ \{\ return\ 0\ \}\n\n\ \ \ \ ::InstallJammer::ExecuteActions\ \$id\ -when\ \$when\n\n\ \ \ \ set\ info(UserMovedBack)\ 0\n\ \ \ \ set\ info(UserMovedNext)\ 1\n\n\ \ \ \ return\ 1\n\}\n\n##\ This\ command\ is\ executed\ before\ the\ installer\ is\ cancelled.\n##\ Uses\ the\ wizard's\ -cancelcommand\ option.\nproc\ ::InstallJammer::CancelCommand\ \{\ wizard\ id\ \}\ \{\n\ \ \ \ set\ when\ \"Before\ Pane\ is\ Cancelled\"\n\n\ \ \ \ if\ \{!\[\$id\ checkConditions\ \$when\]\}\ \{\ return\ 0\ \}\n\n\ \ \ \ ::InstallJammer::ExecuteActions\ \$id\ -when\ \$when\n\n\ \ \ \ return\ 1\n\}\n\n##\ Uses\ the\ wizard's\ <<WizardCancel>>\ event.\nproc\ ::InstallJammer::CancelEventHandler\ \{\ wizard\ \}\ \{\n\ \ \ \ #set\ id\ \[\$wizard\ raise\]\n\n\ \ \ \ #set\ when\ \"After\ Pane\ is\ Cancelled\"\n\ \ \ \ #::InstallJammer::ExecuteActions\ \$id\ -when\ \$when\n\n\ \ \ \ ::InstallJammer::exit\ 1\n\}\n\n##\ This\ command\ is\ executed\ before\ the\ installer\ is\ finished.\n##\ Uses\ the\ wizard's\ -finishcommand\ option.\nproc\ ::InstallJammer::FinishCommand\ \{\ wizard\ id\ \}\ \{\n\ \ \ \ set\ when\ \"Before\ Pane\ is\ Finished\"\n\n\ \ \ \ if\ \{!\[\$id\ checkConditions\ \$when\]\}\ \{\ return\ 0\ \}\n\n\ \ \ \ ::InstallJammer::ExecuteActions\ \$id\ -when\ \$when\n\n\ \ \ \ return\ 1\n\}\n\n##\ Uses\ the\ wizard's\ <<WizardFinish>>\ event.\nproc\ ::InstallJammer::FinishEventHandler\ \{\ wizard\ \}\ \{\n\ \ \ \ set\ id\ \[\$wizard\ raise\]\n\n\ \ \ \ set\ when\ \"After\ Pane\ is\ Finished\"\n\ \ \ \ ::InstallJammer::ExecuteActions\ \$id\ -when\ \$when\n\n\ \ \ \ ::InstallJammer::exit\n\}\n\n##\ This\ command\ is\ executed\ before\ the\ next\ pane\ is\ displayed\ but\n##\ after\ the\ wizard\ has\ moved\ forward.\n##\ Uses\ the\ wizard's\ -raisecommand\ option.\nproc\ ::InstallJammer::RaiseCommand\ \{\ wizard\ id\ \}\ \{\n\ \ \ \ set\ when\ \"Before\ Pane\ is\ Displayed\"\n\ \ \ \ ::InstallJammer::ExecuteActions\ \$id\ -when\ \$when\n\}\n\n##\ Uses\ the\ wizard's\ <<WizardStep>>\ event.\nproc\ ::InstallJammer::RaiseEventHandler\ \{\ wizard\ \}\ \{\n\ \ \ \ global\ conf\n\ \ \ \ global\ info\n\n\ \ \ \ set\ id\ \[\$wizard\ raise\]\n\n\ \ \ \ set\ info(CurrentPane)\ \$id\n\n\ \ \ \ if\ \{!\[\$id\ active\]\ ||\ !\[\$id\ checkConditions\ \"Before\ Pane\ is\ Displayed\"\]\}\ \{\n\ \ \ \ \ \ \ \ ##\ This\ pane\ is\ inactive\ or\ doesn't\ meet\ its\ conditions.\n\ \ \ \ \ \ \ \ ##\ Remove\ it\ from\ the\ order\ of\ the\ wizard\ and\ continue\ on\n\ \ \ \ \ \ \ \ ##\ to\ the\ next\ pane.\n\n\ \ \ \ \ \ \ \ if\ \{!\[\$id\ active\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ debug\ \"Skipping\ pane\ \$id\ -\ \[\$id\ title\]\ -\ pane\ is\ inactive\"\ \$id\n\ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ debug\ \"Skipping\ pane\ \$id\ -\ \[\$id\ title\]\ -\ conditions\ failed\"\ \$id\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \$wizard\ order\ \[lrange\ \[\$wizard\ order\]\ 0\ end-1\]\n\ \ \ \ \ \ \ \ ::InstallJammer::Wizard\ next\ 1\ 0\n\ \ \ \ \ \ \ \ return\n\ \ \ \ \}\n\n\ \ \ \ debug\ \"Displaying\ pane\ \$id\ -\ \[\$id\ title\]\"\ \$id\n\n\ \ \ \ ##\ If\ the\ last\ step\ we\ displayed\ was\ a\ window\ and\ not\ part\n\ \ \ \ ##\ of\ the\ wizard,\ we\ need\ to\ withdraw\ the\ window\ as\ we\ move\ on.\n\ \ \ \ if\ \{\[info\ exists\ conf(LastStepId)\]\ &&\ \[\$conf(LastStepId)\ is\ window\]\}\ \{\n\ \ \ \ \ \ \ \ set\ window\ \[\$conf(LastStepId)\ window\]\n\ \ \ \ \ \ \ \ ::InstallJammer::TransientParent\ \$window\ 1\n\ \ \ \ \ \ \ \ wm\ withdraw\ \$window\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ ::InstallJammer::TransientParent\ \$wizard\ 1\n\ \ \ \ \}\n\n\ \ \ \ ##\ If\ this\ component\ is\ a\ window,\ we\ need\ to\ withdraw\ the\n\ \ \ \ ##\ wizard\ and\ display\ it.\n\ \ \ \ if\ \{\[\$id\ is\ window\]\}\ \{\n\ \ \ \ \ \ \ \ set\ base\ \[\$id\ window\]\n\ \ \ \ \ \ \ \ ::InstallJammer::TransientParent\ \$base\n\n\ \ \ \ \ \ \ \ wm\ withdraw\ \$wizard\ \n\n\ \ \ \ \ \ \ \ ::InstallJammer::UpdateWidgets\ -buttons\ 0\n\n\ \ \ \ \ \ \ \ if\ \{!\[\$id\ get\ Modal\ \ modal\]\}\ \ \{\ set\ modal\ \ 0\ \}\n\ \ \ \ \ \ \ \ if\ \{!\[\$id\ get\ Dialog\ dialog\]\}\ \{\ set\ dialog\ 0\ \}\n\n\ \ \ \ \ \ \ \ if\ \{\[winfo\ exists\ \$base\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ wm\ deiconify\ \$base\n\ \ \ \ \ \ \ \ \ \ \ \ raise\ \$base\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$modal\}\ \{\ ::InstallJammer::Grab\ set\ \$base\ \}\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ update\n\n\ \ \ \ \ \ \ \ set\ when\ \"After\ Pane\ is\ Displayed\"\n\ \ \ \ \ \ \ \ ::InstallJammer::ExecuteActions\ \$id\ -when\ \$when\n\n\ \ \ \ \ \ \ \ if\ \{\[winfo\ exists\ \$base\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$dialog\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[\$id\ get\ DialogVairiable\ varName\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ tkwait\ variable\ \$varName\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ tkwait\ window\ \$base\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$modal\}\ \{\ ::InstallJammer::Grab\ release\ \$base\ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ ::InstallJammer::TransientParent\ \$wizard\n\ \ \ \ \ \ \ \ ::InstallJammer::UpdateWidgets\ -wizard\ \$wizard\ -step\ \$id\n\n\ \ \ \ \ \ \ \ \$wizard\ show\n\ \ \ \ \ \ \ \ update\n\n\ \ \ \ \ \ \ \ set\ when\ \"After\ Pane\ is\ Displayed\"\n\ \ \ \ \ \ \ \ ::InstallJammer::ExecuteActions\ \$id\ -when\ \$when\n\ \ \ \ \}\n\n\ \ \ \ set\ info(WizardFirstStep)\ 0\n\ \ \ \ set\ info(WizardLastStep)\ \ 0\n\n\ \ \ \ set\ conf(LastStepId)\ \$id\n\}\n\nproc\ ::InstallJammer::UpdateWizardButtons\ \{\ args\ \}\ \{\n\ \ \ \ global\ info\n\n\ \ \ \ if\ \{\[llength\ \$args\]\}\ \{\n\ \ \ \ \ \ \ \ lassign\ \$args\ wizard\ id\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ set\ wizard\ \$info(Wizard)\n\ \ \ \ \ \ \ \ set\ id\ \[\$wizard\ raise\]\n\ \ \ \ \}\n\n\ \ \ \ if\ \{!\[\$id\ get\ Buttons\ buttons\]\}\ \{\ return\ \}\n\n\ \ \ \ foreach\ button\ \[list\ back\ next\ cancel\ finish\ help\]\ \{\n\ \ \ \ \ \ \ \ if\ \{!\[\$wizard\ exists\ \$button\]\}\ \{\ continue\ \}\n\n\ \ \ \ \ \ \ \ set\ text\ \[string\ totitle\ \$button\]\n\ \ \ \ \ \ \ \ if\ \{\[string\ match\ \"*\$text*\"\ \$buttons\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \$wizard\ itemconfigure\ \$button\ -hide\ 0\n\n\ \ \ \ \ \ \ \ \ \ \ \ set\ w\ \[\$wizard\ widget\ get\ \$button\ -step\ \$id\]\n\ \ \ \ \ \ \ \ \ \ \ \ ::InstallJammer::SetText\ \$w\ \$id\ \[string\ toupper\ \$button\ 0\]Button\n\ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \$wizard\ itemconfigure\ \$button\ -hide\ 1\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::Wizard\ \{\ args\ \}\ \{\n\ \ \ \ global\ info\n\n\ \ \ \ set\ wizard\ \$info(Wizard)\n\n\ \ \ \ if\ \{!\[llength\ \$args\]\}\ \{\ return\ \$wizard\ \}\n\n\ \ \ \ set\ command\ \[lindex\ \$args\ 0\]\n\ \ \ \ set\ args\ \ \ \ \[lrange\ \$args\ 1\ end\]\n\n\ \ \ \ set\ id\ \[::InstallJammer::ID\ \[lindex\ \$args\ 0\]\]\n\n\ \ \ \ switch\ --\ \$command\ \{\n\ \ \ \ \ \ \ \ \"back\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{!\[llength\ \$args\]\}\ \{\ set\ args\ 1\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ eval\ \[list\ \$info(Wizard)\ back\]\ \$args\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \"next\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{!\[llength\ \$args\]\}\ \{\ set\ args\ 1\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ eval\ \[list\ \$info(Wizard)\ next\]\ \$args\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \"create\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ ::InstallJammer::CreateWindow\ \$wizard\ \$id\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \"raise\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ args\ \[lreplace\ \$args\ 0\ 0\ \$id\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[llength\ \$args\]\ ==\ 1\}\ \{\ lappend\ args\ 1\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ eval\ \[list\ \$info(Wizard)\ raise\]\ \$args\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \"show\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \$wizard\ show\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \"hide\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$id\ eq\ \"\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \$wizard\ hide\n\ \ \ \ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ wm\ withdraw\ \[\$id\ window\]\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::CreateWindow\ \{\ wizard\ id\ \{preview\ 0\}\ \}\ \{\n\ \ \ \ set\ id\ \ \ \ \[::InstallJammer::ID\ \$id\]\n\ \ \ \ set\ pane\ \ \[\$id\ component\]\n\ \ \ \ set\ istop\ \[\$id\ is\ window\]\n\n\ \ \ \ set\ base\ \ .\[\$id\ name\]\n\n\ \ \ \ if\ \{\$istop\}\ \{\n\ \ \ \ \ \ \ \ if\ \{\[winfo\ exists\ \$base\]\}\ \{\ return\ \$base\ \}\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ if\ \{\[\$wizard\ exists\ \$id\]\ &&\ (\$preview\ ||\ \[\$id\ created\])\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ return\ \[\$wizard\ widget\ get\ \$id\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ set\ parent\ \[\$id\ parent\]\n\n\ \ \ \ if\ \{\$preview\ &&\ !\[\$wizard\ exists\ \$id\]\}\ \{\n\ \ \ \ \ \ \ \ set\ parent\ root\n\ \ \ \ \ \ \ \ \$id\ get\ WizardOptions\ opts\n\ \ \ \ \ \ \ \ eval\ \[list\ \$wizard\ insert\ step\ end\ \$parent\ \$id\]\ \$opts\n\ \ \ \ \}\n\n\ \ \ \ if\ \{!\$preview\ &&\ \[\$wizard\ exists\ \$id\]\}\ \{\n\ \ \ \ \ \ \ \ \$wizard\ itemconfigure\ \$id\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ -backcommand\ \ \ \[list\ ::InstallJammer::BackCommand\ \ \$wizard\ \$id\]\ \ \\\n\ \ \ \ \ \ \ \ \ \ \ \ -nextcommand\ \ \ \[list\ ::InstallJammer::NextCommand\ \ \$wizard\ \$id\]\ \ \\\n\ \ \ \ \ \ \ \ \ \ \ \ -raisecommand\ \ \[list\ ::InstallJammer::RaiseCommand\ \$wizard\ \$id\]\ \ \\\n\ \ \ \ \ \ \ \ \ \ \ \ -cancelcommand\ \[list\ ::InstallJammer::CancelCommand\ \$wizard\ \$id\]\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ -finishcommand\ \[list\ ::InstallJammer::FinishCommand\ \$wizard\ \$id\]\n\n\ \ \ \ \ \ \ \ bind\ \$wizard\ <<WizardStep>>\ \ \ \"::InstallJammer::RaiseEventHandler\ \ %W\"\n\ \ \ \ \ \ \ \ bind\ \$wizard\ <<WizardCancel>>\ \"::InstallJammer::CancelEventHandler\ %W\"\n\ \ \ \ \ \ \ \ bind\ \$wizard\ <<WizardFinish>>\ \"::InstallJammer::FinishEventHandler\ %W\"\n\n\ \ \ \ \ \ \ \ bind\ \$wizard\ <<WizardLastStep>>\ \ \"set\ ::info(WizardLastStep)\ \ 1\"\n\ \ \ \ \ \ \ \ bind\ \$wizard\ <<WizardFirstStep>>\ \"set\ ::info(WizardFirstStep)\ 1\"\n\n\ \ \ \ \ \ \ \ \$id\ created\ 1\n\ \ \ \ \}\n\n\ \ \ \ set\ proc\ \[GetPaneProc\ \$id\ CreateWindow\]\n\n\ \ \ \ if\ \{\[string\ length\ \$proc\]\}\ \{\n\ \ \ \ \ \ \ \ if\ \{!\$istop\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \$wizard\ createstep\ \$id\n\n\ \ \ \ \ \ \ \ \ \ \ \ \$proc\ \$wizard\ \$id\n\ \ \ \ \ \ \ \ \ \ \ \ set\ base\ \[\$wizard\ widget\ get\ \$id\]\n\ \ \ \ \ \ \ \ \ \ \ \ \$id\ window\ \$base\n\ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \$id\ window\ \$base\n\ \ \ \ \ \ \ \ \ \ \ \ \$proc\ \$wizard\ \$id\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ return\ \$base\n\}\n\nproc\ ::InstallJammer::TransientParent\ \{\ \{parent\ \"\"\}\ \{remove\ 0\}\ \}\ \{\n\ \ \ \ global\ conf\n\ \ \ \ if\ \{\[string\ length\ \$parent\]\}\ \{\n\ \ \ \ \ \ \ \ if\ \{\$remove\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ conf(ParentWindow)\ \[lremove\ \$conf(ParentWindow)\ \$parent\]\n\ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ conf(ParentWindow)\ \$parent\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ if\ \{\[info\ exists\ conf(ParentWindow)\]\}\ \{\n\ \ \ \ \ \ \ \ return\ \[lindex\ \$conf(ParentWindow)\ end\]\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::SetObjectProperties\ \{\ id\ args\ \}\ \{\n\ \ \ \ variable\ ::InstallJammer::Properties\n\n\ \ \ \ array\ set\ data\ \{\n\ \ \ \ \ \ \ \ -safe\ \ \ \ \ \ \ 0\n\ \ \ \ \ \ \ \ -nocomplain\ 0\n\ \ \ \ \}\n\n\ \ \ \ set\ idx\ 0\n\ \ \ \ foreach\ arg\ \$args\ \{\n\ \ \ \ \ \ \ \ if\ \{\[info\ exists\ data(\$arg)\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ data(\$arg)\ 1\n\ \ \ \ \ \ \ \ \ \ \ \ incr\ idx\n\ \ \ \ \ \ \ \ \}\ elseif\ \{\$arg\ eq\ \"--\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ incr\ indx\n\ \ \ \ \ \ \ \ \ \ \ \ break\n\ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ break\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ set\ args\ \[lrange\ \$args\ \$idx\ end\]\n\n\ \ \ \ if\ \{\[llength\ \$args\]\ ==\ 1\}\ \{\n\ \ \ \ \ \ \ \ set\ property\ \[lindex\ \$args\ 0\]\n\ \ \ \ \ \ \ \ if\ \{\$data(-nocomplain)\n\ \ \ \ \ \ \ \ \ \ \ \ &&\ !\[info\ exists\ Properties(\$id,\$property)\]\}\ \{\ return\ \}\n\ \ \ \ \ \ \ \ return\ \$Properties(\$id,\$property)\n\ \ \ \ \}\n\n\ \ \ \ foreach\ \[list\ property\ value\]\ \$args\ \{\n\ \ \ \ \ \ \ \ if\ \{!\$data(-safe)\ ||\ !\[info\ exists\ Properties(\$id,\$property)\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$property\ eq\ \"Alias\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ ::InstallJammer::aliases\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ ::InstallJammer::aliasmap\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[info\ exists\ aliasmap(\$id)\]\}\ \{\ \$id\ CleanupAlias\ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$value\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ aliases(\$value)\ \$id\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ aliasmap(\$id)\ \$value\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$property\ eq\ \"Active\"\}\ \{\ \$id\ active\ \$value\ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ set\ Properties(\$id,\$property)\ \$value\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ return\ \$Properties(\$id,\$property)\n\}\n\nproc\ ::InstallJammer::GetObjectProperty\ \{\ id\ property\ \{varName\ \"\"\}\ \}\ \{\n\ \ \ \ variable\ ::InstallJammer::Properties\n\n\ \ \ \ if\ \{\[string\ length\ \$varName\]\}\ \{\n\ \ \ \ \ \ \ \ upvar\ 1\ \$varName\ var\n\ \ \ \ \ \ \ \ set\ var\ \"\"\n\ \ \ \ \ \ \ \ if\ \{!\[info\ exists\ Properties(\$id,\$property)\]\}\ \{\ return\ 0\ \}\n\ \ \ \ \ \ \ \ set\ var\ \$Properties(\$id,\$property)\n\ \ \ \ \ \ \ \ return\ 1\n\ \ \ \ \}\n\n\ \ \ \ if\ \{\[info\ exists\ Properties(\$id,\$property)\]\}\ \{\n\ \ \ \ \ \ \ \ return\ \$Properties(\$id,\$property)\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::ObjectProperties\ \{\ id\ arrayName\ args\ \}\ \{\n\ \ \ \ upvar\ 1\ \$arrayName\ array\n\ \ \ \ variable\ ::InstallJammer::Properties\n\n\ \ \ \ set\ subst\ \[list\]\n\ \ \ \ if\ \{\[set\ x\ \[lsearch\ -exact\ \$args\ \"-subst\"\]\]\ >\ -1\}\ \{\n\ \ \ \ \ \ \ \ set\ subst\ \[lindex\ \$args\ \[expr\ \{\$x\ +\ 1\}\]\]\n\ \ \ \ \ \ \ \ set\ args\ \ \[lreplace\ \$args\ \$x\ \[incr\ x\]\]\n\ \ \ \ \}\n\n\ \ \ \ set\ slen\ \[llength\ \$subst\]\n\n\ \ \ \ if\ \{!\[llength\ \$args\]\}\ \{\n\ \ \ \ \ \ \ \ foreach\ varName\ \[array\ names\ Properties\ \$id,*\]\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ var\ \[string\ map\ \[list\ \$id,\ \"\"\]\ \$varName\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ val\ \$Properties(\$varName)\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$slen\ &&\ (\$subst\ eq\ \"1\"\ ||\ \[lsearch\ -exact\ \$subst\ \$var\]\ >\ -1)\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ val\ \[::InstallJammer::SubstText\ \$val\]\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ set\ array(\$var)\ \$val\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ foreach\ var\ \$args\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{!\[info\ exists\ Properties(\$id,\$var)\]\}\ \{\ continue\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ set\ val\ \$Properties(\$id,\$var)\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$slen\ &&\ (\$subst\ eq\ \"1\"\ ||\ \[lsearch\ -exact\ \$subst\ \$var\]\ >\ -1)\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ val\ \[::InstallJammer::SubstText\ \$val\]\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ set\ array(\$var)\ \$val\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::SetTitle\ \{\ w\ id\ \}\ \{\n\ \ \ \ set\ id\ \[::InstallJammer::ID\ \$id\]\n\ \ \ \ set\ title\ \[::InstallJammer::GetText\ \$id\ Title\]\n\ \ \ \ wm\ title\ \$w\ \$title\n\}\n\nproc\ ::InstallJammer::SetVirtualText\ \{\ languages\ window\ args\ \}\ \{\n\ \ \ \ if\ \{\[llength\ \$args\]\ ==\ 1\}\ \{\ set\ args\ \[lindex\ \$args\ 0\]\ \}\n\n\ \ \ \ if\ \{\$languages\ eq\ \"all\"\}\ \{\ set\ languages\ \[GetLanguageCodes\]\ \}\n\n\ \ \ \ foreach\ lang\ \$languages\ \{\n\ \ \ \ \ \ \ \ if\ \{\$lang\ eq\ \"None\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ global\ info\n\ \ \ \ \ \ \ \ \ \ \ \ foreach\ \{name\ value\}\ \$args\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ info(\$name)\ \$value\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ debug\ \"Virtual\ Text\ \$name\ is\ now\ set\ to\ \$value\"\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ foreach\ \{name\ value\}\ \$args\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::msgcat::mcset\ \$lang\ \$window,\$name\ \$value\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::GetText\ \{\ id\ field\ args\ \}\ \{\n\ \ \ \ global\ info\n\n\ \ \ \ array\ set\ _args\ \{\n\ \ \ \ \ \ \ \ -subst\ \ \ \ \ \ 1\n\ \ \ \ \ \ \ \ -language\ \ \ \"\"\n\ \ \ \ \ \ \ \ -forcesubst\ 0\n\ \ \ \ \}\n\ \ \ \ array\ set\ _args\ \$args\n\n\ \ \ \ set\ id\ \ \ \[::InstallJammer::ID\ \$id\]\n\ \ \ \ set\ item\ \[\$id\ component\]\n\n\ \ \ \ if\ \{\[string\ length\ \$_args(-language)\]\}\ \{\n\ \ \ \ \ \ \ \ set\ found\ 0\n\ \ \ \ \ \ \ \ foreach\ lang\ \[concat\ \$_args(-language)\ en\]\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ text\ \[::msgcat::mcget\ \$lang\ \$id,\$field\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$text\ eq\ \"\$id,\$field\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ text\ \[::msgcat::mcget\ \$lang\ \$item,\$field\]\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$text\ ne\ \"\$item,\$field\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ found\ 1\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ break\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ if\ \{!\$found\}\ \{\ return\ \}\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ set\ text\ \[::msgcat::mc\ \$id,\$field\]\n\ \ \ \ \ \ \ \ if\ \{\$text\ eq\ \"\$id,\$field\"\}\ \{\ set\ text\ \[::msgcat::mc\ \$item,\$field\]\ \}\n\ \ \ \ \ \ \ \ if\ \{\$text\ eq\ \"\$item,\$field\"\}\ \{\ return\ \}\n\ \ \ \ \}\n\n\ \ \ \ if\ \{\$_args(-forcesubst)\n\ \ \ \ \ \ \ \ ||\ (\$_args(-subst)\ &&\ \[\$id\ get\ \$field,subst\ subst\]\ &&\ \$subst)\}\ \{\n\ \ \ \ \ \ \ \ set\ text\ \[::InstallJammer::SubstText\ \$text\]\n\ \ \ \ \}\n\n\ \ \ \ return\ \$text\n\}\n\nproc\ ::InstallJammer::SetText\ \{\ args\ \}\ \{\n\ \ \ \ if\ \{\[llength\ \$args\]\ ==\ 3\}\ \{\n\ \ \ \ \ \ \ \ lassign\ \$args\ w\ id\ field\n\ \ \ \ \ \ \ \ set\ id\ \ \ \[::InstallJammer::ID\ \$id\]\n\ \ \ \ \ \ \ \ set\ text\ \[::InstallJammer::GetText\ \$id\ \$field\]\n\ \ \ \ \}\ elseif\ \{\[llength\ \$args\]\ ==\ 2\}\ \{\n\ \ \ \ \ \ \ \ lassign\ \$args\ w\ text\n\ \ \ \ \}\n\n\ \ \ \ if\ \{!\[winfo\ exists\ \$w\]\}\ \{\ return\ \}\n\n\ \ \ \ set\ class\ \[winfo\ class\ \$w\]\n\n\ \ \ \ if\ \{\$class\ eq\ \"Text\"\}\ \{\n\t\$w\ configure\ -state\ normal\n\t\$w\ delete\ 0.0\ end\n\t\$w\ insert\ end\ \$text\n\t\$w\ configure\ -state\ disabled\n\ \ \ \ \}\ elseif\ \{\$class\ eq\ \"Label\"\ &&\ \[string\ length\ \[\$w\ cget\ -textvariable\]\]\}\ \{\n\ \ \ \ \ \ \ \ set\ \[\$w\ cget\ -textvariable\]\ \$text\n\ \ \ \ \}\ else\ \{\n\t\$w\ configure\ -text\ \$text\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::Image\ \{\ id\ image\ \}\ \{\n\ \ \ \ global\ images\n\n\ \ \ \ set\ id\ \ \ \ \[::InstallJammer::ID\ \$id\]\n\ \ \ \ set\ image\ \$id,\$image\n\n\ \ \ \ if\ \{!\[ImageExists\ \$image\]\}\ \{\ set\ image\ \[\$id\ component\],\$image\ \}\n\ \ \ \ if\ \{\[ImageExists\ \$image\]\}\ \{\ return\ \$images(\$image)\ \}\n\}\n\nproc\ ::InstallJammer::SetImage\ \{\ w\ id\ image\ \}\ \{\n\ \ \ \ set\ image\ \[::InstallJammer::Image\ \$id\ \$image\]\n\ \ \ \ if\ \{\[string\ length\ \$image\]\}\ \{\ \$w\ configure\ -image\ \$image\ \}\n\}\n\nproc\ ::InstallJammer::ImageExists\ \{img\}\ \{\n\ \ \ \ global\ images\n\ \ \ \ return\ \[info\ exists\ images(\$img)\]\n\}\n\nproc\ ::InstallJammer::UpdateWidgets\ \{\ args\ \}\ \{\n\ \ \ \ global\ info\n\n\ \ \ \ if\ \{\$info(SilentMode)\}\ \{\ return\ \}\n\n\ \ \ \ array\ set\ _args\ \{\n\ \ \ \ \ \ \ \ -update\ \ \ \ \ \ \ \ \ \ 0\n\ \ \ \ \ \ \ \ -buttons\ \ \ \ \ \ \ \ \ 1\n\ \ \ \ \ \ \ \ -widgets\ \ \ \ \ \ \ \ \ \{\}\n\ \ \ \ \ \ \ \ -updateidletasks\ 0\n\ \ \ \ \}\n\n\ \ \ \ array\ set\ _args\ \$args\n\n\ \ \ \ if\ \{!\[info\ exists\ _args(-wizard)\]\}\ \{\ set\ _args(-wizard)\ \$info(Wizard)\ \}\n\ \ \ \ set\ wizard\ \$_args(-wizard)\n\n\ \ \ \ if\ \{!\[winfo\ exists\ \$wizard\]\}\ \{\ return\ \}\n\n\ \ \ \ if\ \{!\[info\ exists\ _args(-step)\]\}\ \{\ set\ _args(-step)\ \[\$wizard\ raise\]\ \}\n\ \ \ \ set\ step\ \$_args(-step)\n\n\ \ \ \ if\ \{!\[string\ length\ \$step\]\}\ \{\ return\ \}\n\n\ \ \ \ if\ \{!\[llength\ \$_args(-widgets)\]\}\ \{\ set\ _args(-widgets)\ \[\$step\ widgets\]\ \}\n\ \ \ \ \n\ \ \ \ foreach\ widget\ \$_args(-widgets)\ \{\n\ \ \ \ \ \ \ \ set\ w\ \[\$step\ widget\ get\ \$widget\]\n\ \ \ \ \ \ \ \ if\ \{!\[winfo\ exists\ \$w\]\}\ \{\ continue\ \}\n\n\ \ \ \ \ \ \ \ switch\ --\ \[\$step\ widget\ type\ \$widget\]\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \"progress\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ value\ \[::InstallJammer::GetText\ \$step\ \$widget\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ is\ integer\ -strict\ \$value\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \$w\ configure\ -value\ \$value\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \"image\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::InstallJammer::SetImage\ \$w\ \$step\ \$widget\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \"text\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::InstallJammer::SetText\ \$w\ \$step\ \$widget\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ if\ \{\$_args(-buttons)\}\ \{\ ::InstallJammer::UpdateWizardButtons\ \$wizard\ \$step\ \}\n\n\ \ \ \ if\ \{\$_args(-update)\}\ \{\ set\ _args(-updateidletasks)\ 0\;\ update\ \}\n\n\ \ \ \ if\ \{\$_args(-updateidletasks)\}\ \{\ update\ idletasks\ \}\n\}\n\nproc\ ::InstallJammer::DirIsWritable\ \{dir\}\ \{\n\ \ \ \ if\ \{\$::tcl_platform(platform)\ eq\ \"windows\"\}\ \{\n\tif\ \{\[catch\ \{file\ attributes\ \$dir\}\ error\]\}\ \{\ return\ 0\ \}\n\treturn\ 1\n\ \ \ \ \}\n\ \ \ \ return\ \[file\ writable\ \$dir\]\n\}\n\nproc\ ::InstallJammer::Normalize\ \{\ file\ \{style\ none\}\ \}\ \{\n\ \ \ \ if\ \{\[string\ length\ \$file\]\}\ \{\n\ \ \ \ \ \ \ \ set\ file\ \[eval\ file\ join\ \[file\ split\ \$file\]\]\n\ \ \ \ \ \ \ \ switch\ --\ \$style\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \"unix\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ index\ \$file\ 1\]\ ==\ \":\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ file\ \[string\ range\ \$file\ 2\ end\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \"windows\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ file\ \[string\ map\ \[list\ /\ \\\\\]\ \$file\]\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ return\ \$file\n\}\n\nproc\ ::InstallJammer::RelativeFile\ \{\ file\ \}\ \{\n\ \ \ \ if\ \{\[file\ pathtype\ \$file\]\ eq\ \"relative\"\}\ \{\n\ \ \ \ \ \ \ \ set\ file\ \[::InstallJammer::SubstText\ \"<%InstallDir%>/\$file\"\]\n\ \ \ \ \}\n\ \ \ \ return\ \[::InstallJammer::Normalize\ \$file\]\n\}\n\nproc\ ::InstallJammer::RollbackName\ \{\ file\ \}\ \{\n\ \ \ \ global\ info\n\ \ \ \ return\ \[file\ join\ \[file\ dirname\ \$file\]\ .\$info(InstallID).\[file\ tail\ \$file\]\]\n\}\n\nproc\ ::InstallJammer::SaveForRollback\ \{file\}\ \{\n\ \ \ \ file\ rename\ -force\ \$file\ \[::InstallJammer::RollbackName\ \$file\]\n\}\n\nproc\ ::InstallJammer::WindowsDir\ \{\ dir\ \}\ \{\n\ \ \ \ if\ \{\[catch\ \{\ ::Windows::folder\ \$dir\ \}\ windir\]\}\ \{\ set\ windir\ \"\"\ \}\n\ \ \ \ if\ \{\[string\ length\ \$windir\]\}\ \{\ return\ \[Normalize\ \$windir\ windows\]\ \}\n\n\ \ \ \ ##\ We\ couldn't\ find\ the\ directory\ they\ were\ looking\ for.\n\ \ \ \ ##\ See\ if\ we\ can\ give\ them\ something.\n\n\ \ \ \ if\ \{\[string\ match\ \"COMMON_*\"\ \$dir\]\}\ \{\n\ \ \ \ \ \ \ \ ##\ Windows\ 9x\ doesn't\ support\ COMMON_*\ directories,\ so\ let's\n\ \ \ \ \ \ \ \ ##\ see\ if\ we\ can\ give\ them\ the\ normal\ one.\n\ \ \ \ \ \ \ \ set\ chk\ \[string\ range\ \$dir\ 7\ end\]\n\ \ \ \ \ \ \ \ if\ \{\[catch\ \{\ ::Windows::folder\ \$chk\ \}\ windir\]\}\ \{\ set\ windir\ \"\"\ \}\n\ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$windir\]\}\ \{\ return\ \[Normalize\ \$windir\ windows\]\ \}\n\ \ \ \ \}\n\n\ \ \ \ set\ key\ \{HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\}\n\n\ \ \ \ switch\ --\ \$dir\ \{\n\t\"WINDOWS\"\ \{\n\t\ \ \ \ if\ \{\[info\ exists\ ::env(windir)\]\}\ \{\n\t\tset\ windir\ \$::env(windir)\n\t\ \ \ \ \}\ elseif\ \{\[info\ exists\ ::env(SYSTEMROOT)\]\}\ \{\n\t\tset\ windir\ \$::env(SYSTEMROOT)\n\t\ \ \ \ \}\ elseif\ \{!\[catch\ \{registry\ get\ \$key\ SystemRoot\}\ result\]\}\ \{\n\t\tset\ windir\ \$result\n\t\ \ \ \ \}\ else\ \{\n\t\tset\ windir\ \"C:\\\\Windows\"\n\t\ \ \ \ \}\n\t\}\n\n\t\"PROGRAM_FILES\"\ \{\n\t\ \ \ \ if\ \{\[info\ exists\ ::env(ProgramFiles)\]\}\ \{\n\t\tset\ windir\ \$::env(ProgramFiles)\n\t\ \ \ \ \}\ elseif\ \{!\[catch\ \{registry\ get\ \$key\ ProgramFilesDir\}\ result\]\}\ \{\n\t\tset\ windir\ \$result\n\t\ \ \ \ \}\ else\ \{\n\t\tset\ windir\ \"C:\\\\Program\ Files\"\n\t\ \ \ \ \}\n\t\}\n\n\t\"SYSTEM\"\ \{\n\t\ \ \ \ set\ windir\ \[file\ join\ \[WindowsDir\ WINDOWS\]\ system\]\n\t\}\n\n\t\"SYSTEM32\"\ \{\n\t\ \ \ \ set\ windir\ \[file\ join\ \[WindowsDir\ WINDOWS\]\ system32\]\n\t\}\n\n\t\"QUICK_LAUNCH\"\ \{\n\t\ \ \ \ set\ windir\ \[WindowsDir\ APPDATA\]\n\t\ \ \ \ set\ windir\ \[file\ join\ \$windir\ \\\n\t\ \ \ \ \t\"Microsoft\"\ \"Internet\ Explorer\"\ \"Quick\ Launch\"\]\n\t\}\n\n\t\"WALLPAPER\"\ \{\n\t\ \ \ \ set\ windir\ \[registry\ get\ \$key\ WallPaperDir\]\n\t\}\n\n\tdefault\ \{\n\t\ \ \ \ ##\ Couldn't\ find\ a\ directory.\ \ Just\ return\ the\ string.\n\t\ \ \ \ return\ <%\$dir%>\n\t\}\n\ \ \ \ \}\n\n\ \ \ \ return\ \[Normalize\ \$windir\ windows\]\n\}\n\nproc\ ::InstallJammer::SetupRegVirtualText\ \{\}\ \{\n\ \ \ \ global\ info\n\n\ \ \ \ set\ env\ \ \ \ \ \ \ \ \{HKEY_LOCAL_MACHINE\}\n\ \ \ \ set\ user\ \ \ \ \ \ \ \{HKEY_CURRENT_USER\}\n\ \ \ \ set\ current\ \ \ \ \{HKEY_LOCAL_MACHINE\}\n\ \ \ \ append\ env\ \ \ \ \ \{\\SYSTEM\\CurrentControlSet\\Control\\Session\ Manager\}\n\ \ \ \ append\ current\ \{\\Software\\Microsoft\\Windows\\CurrentVersion\}\n\n\ \ \ \ set\ info(REG_USER_ENV)\ \ \ \ \ \ \ \ \"\$user\\\\Environment\"\n\ \ \ \ set\ info(REG_SYSTEM_ENV)\ \ \ \ \ \ \"\$env\\\\Environment\"\n\ \ \ \ set\ info(REG_UNINSTALL)\ \ \ \ \ \ \ \"\$current\\\\Uninstall\"\n\ \ \ \ set\ info(REG_CURRENT_VERSION)\ \"\$current\"\n\n\ \ \ \ return\n\}\n\nproc\ ::InstallJammer::SetWindowsPlatform\ \{\}\ \{\n\ \ \ \ global\ conf\n\ \ \ \ global\ info\n\n\ \ \ \ set\ string\ Windows\n\n\ \ \ \ if\ \{\$conf(windows)\}\ \{\n\ \ \ \ \ \ \ \ switch\ --\ \$::tcl_platform(os)\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \"Windows\ 95\"\ \{\ set\ string\ \"Win95\"\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \"Windows\ 98\"\ \{\ set\ string\ \"Win98\"\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \"Windows\ NT\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ switch\ --\ \$::tcl_platform(osVersion)\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \"4.0\"\ \{\ set\ string\ \"WinNT\"\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \"5.0\"\ \{\ set\ string\ \"Win2k\"\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \"5.1\"\ \{\ set\ string\ \"WinXP\"\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \"5.2\"\ \{\ set\ string\ \"Win2003\"\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \"6.0\"\ \{\ set\ string\ \"Vista\"\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ set\ info(WindowsPlatform)\ \$string\n\}\n\nproc\ ::InstallJammer::SubstVar\ \{\ var\ \}\ \{\n\ \ \ \ global\ conf\n\ \ \ \ global\ info\n\n\ \ \ \ ##\ See\ if\ this\ is\ a\ virtual\ text\ variable\ that\ exists\ in\n\ \ \ \ ##\ our\ message\ catalog.\ \ If\ it\ does,\ we\ want\ to\ use\ the\n\ \ \ \ ##\ language-specific\ version\ instead\ of\ a\ generic.\n\ \ \ \ if\ \{\[::msgcat::mcexists\ \$var\]\}\ \{\ return\ \[::msgcat::mc\ \$var\]\ \}\n\n\ \ \ \ ##\ If\ this\ variable\ exists\ in\ the\ info\ array,\ return\ its\ value.\n\ \ \ \ if\ \{\[info\ exists\ info(\$var)\]\}\ \{\n\tset\ string\ \$info(\$var)\n\tif\ \{\[lsearch\ -exact\ \$conf(SubstDirVars)\ \$var\]\ >\ -1\}\ \{\n\t\ \ \ \ set\ string\ \[Normalize\ \$string\ \$::tcl_platform(platform)\]\n\t\}\n\ \ \ \treturn\ \$string\n\ \ \ \ \}\n\n\ \ \ \ switch\ -glob\ --\ \$var\ \{\n\t\"Date\ *\"\ \{\n\t\ \ \ \ set\ format\ \[join\ \[lrange\ \$var\ 1\ end\]\]\n\t\ \ \ \ set\ string\ \[clock\ format\ \[clock\ seconds\]\ -format\ \$format\]\n\t\}\n\n\t\"Dir\ *\"\ \{\n\t\ \ \ \ set\ string\ \[join\ \[lrange\ \$var\ 1\ end\]\]\n\t\ \ \ \ set\ string\ \[Normalize\ \$string\ \$::tcl_platform(platform)\]\n\t\}\n\n\ \ \ \ \ \ \ \ \"DiskSpace\ *\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ space\ \ \[lindex\ \$var\ 1\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ string\ \[::InstallJammer::FormatDiskSpace\ \$space\]\n\ \ \ \ \ \ \ \ \}\n\n\t\"FileGroup\ *\"\ \{\n\t\ \ \ \ set\ group\ \[join\ \[lrange\ \$var\ 1\ end\]\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ obj\ \[FindObjByName\ \$group\ \[FileGroups\ children\]\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$obj\]\}\ \{\n\t\tset\ string\ \[\$obj\ directory\]\n\t\tset\ string\ \[Normalize\ \$string\ \$::tcl_platform(platform)\]\n\t\ \ \ \ \}\n\t\}\n\n\t\"GUID\"\ \{\n\t\ \ \ \ set\ string\ \[::InstallJammer::guid\]\n\t\ \ \ \ set\ info(LastGUID)\ \$string\n\t\}\n\n\ \ \ \ \ \ \ \ \"Home\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ string\ \[::InstallJammer::HomeDir\]\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \"InstallInfoDir\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ string\ \[::InstallJammer::InstallInfoDir\]\n\ \ \ \ \ \ \ \ \}\n\n\t\"RegValue\ *\"\ \{\n\t\ \ \ \ set\ list\ \[lrange\ \$var\ 1\ end\]\n\t\ \ \ \ set\ string\ \[::Windows::GetKey\ \[lindex\ \$list\ 0\]\ \[lindex\ \$list\ 1\]\]\n\t\}\n\n\ \ \ \ \ \ \ \ \"SpaceAvailable\"\ -\ \"SpaceAvailable\ *\"\ \{\n\t\ \ \ \ set\ dir\ \[string\ trim\ \[join\ \[lrange\ \$var\ 1\ end\]\]\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{!\[string\ length\ \$dir\]\}\ \{\ set\ dir\ \$info(InstallDir)\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ set\ string\ \[::InstallJammer::GetFreeDiskSpace\ \$dir\]\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \"Tail\ *\"\ \{\n\t\ \ \ \ set\ file\ \[join\ \[lrange\ \$var\ 1\ end\]\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ string\ \[file\ tail\ \$file\]\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \"Temp\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ string\ \[::InstallJammer::TmpDir\]\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \"UUID\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ string\ \[::InstallJammer::uuid\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ info(LastUUID)\ \$string\n\ \ \ \ \ \ \ \ \}\n\n\tdefault\ \{\n\t\ \ \ \ set\ string\ \"<%\$var%>\"\n\n\t\ \ \ \ ##\ If\ the\ string\ is\ all\ uppercase\ and\ didn't\ match\ something\n\t\ \ \ \ ##\ in\ the\ info\ array,\ it's\ a\ Windows\ directory.\n\t\ \ \ \ if\ \{\[string\ length\ \$var\]\ &&\ \$var\ eq\ \[string\ toupper\ \$var\]\}\ \{\n\t\tset\ string\ \[::InstallJammer::WindowsDir\ \$var\]\n\t\ \ \ \ \}\n\t\}\n\ \ \ \ \}\n\n\ \ \ \ return\ \$string\n\}\n\nproc\ ::InstallJammer::SubstForEval\ \{\ string\ \}\ \{\n\ \ \ \ set\ map\ \[list\ \"<%\"\ \{\[::InstallJammer::SubstText\ <%\}\ \"%>\"\ \{%>\]\}\]\n\ \ \ \ return\ \[string\ map\ \$map\ \$string\]\n\}\n\nproc\ ::InstallJammer::SubstForPipe\ \{\ string\ \}\ \{\n\ \ \ \ set\ list\ \[list\]\n\ \ \ \ foreach\ arg\ \$string\ \{\n\ \ \ \ \ \ \ \ lappend\ list\ \[::InstallJammer::SubstText\ \$arg\]\n\ \ \ \ \}\n\ \ \ \ return\ \$list\n\}\n\nproc\ ::InstallJammer::SubstText\ \{\ str\ \{num\ 0\}\ \}\ \{\n\ \ \ \ global\ conf\n\n\ \ \ \ if\ \{\$num\ >\ \$conf(VirtualTextRecursionLimit)\}\ \{\ return\ \$str\ \}\n\n\ \ \ \ if\ \{!\[string\ length\ \$str\]\}\ \{\ return\ \}\n\n\ \ \ \ set\ s\ \$str\n\ \ \ \ set\ s\ \[string\ map\ \$conf(VirtualTextMap)\ \$s\]\n\ \ \ \ set\ s\ \[subst\ -novariables\ \$s\]\n\ \ \ \ if\ \{\$str\ ne\ \$s\}\ \{\ set\ s\ \[::InstallJammer::SubstText\ \$s\ \[incr\ num\]\]\ \}\n\n\ \ \ \ return\ \$s\n\}\n\nproc\ ::InstallJammer::TmpDir\ \{\ \{file\ \"\"\}\ \}\ \{\n\ \ \ \ global\ conf\n\ \ \ \ global\ info\n\n\ \ \ \ if\ \{!\[info\ exists\ info(Temp)\]\ ||\ !\[file\ exists\ \$info(Temp)\]\}\ \{\n\tif\ \{\[info\ exists\ ::env(TEMP)\]\}\ \{\ lappend\ dirs\ \$::env(TEMP)\ \}\n\tif\ \{\[info\ exists\ ::env(TMP)\]\}\ \ \{\ lappend\ dirs\ \$::env(TMP)\ \ \}\n\ \ \ \ \ \ \ \ if\ \{\$conf(windows)\}\ \{\n\t\ \ \ \ lappend\ dirs\ C:/Windows/Temp\n\t\ \ \ \ lappend\ dirs\ C:/WINNT/Temp\n\t\}\ else\ \{\n\t\ \ \ \ lappend\ dirs\ /usr/tmp\ /tmp\ /var/tmp\n\t\}\n\n\ \ \ \ \ \ \ \ set\ subdir\ ijtmp_\[::InstallJammer::uuid\]\n\n\tforeach\ dir\ \$dirs\ \{\n\t\ \ \ \ if\ \{\[DirIsWritable\ \$dir\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ tmpname\ \[file\ join\ \$dir\ \$subdir\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ file\ mkdir\ \$tmpname\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ info(Temp)\ \[Normalize\ \$tmpname\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ break\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\t\}\n\ \ \ \ \}\n\n\ \ \ \ if\ \{\[string\ length\ \$file\]\}\ \{\n\treturn\ \[Normalize\ \[file\ join\ \$info(Temp)\ \$file\]\]\n\ \ \ \ \}\ else\ \{\n\treturn\ \$info(Temp)\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::GetInstallInfoDir\ \{\ \{create\ 0\}\ \}\ \{\n\ \ \ \ global\ conf\n\ \ \ \ global\ info\n\n\ \ \ \ if\ \{!\[info\ exists\ info(InstallInfoDir)\]\}\ \{\n\ \ \ \ \ \ \ \ if\ \{\$conf(windows)\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ root\ \[::InstallJammer::WindowsDir\ PROGRAM_FILES\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ dir\ \ \[file\ join\ \$root\ \"InstallJammer\ Registry\"\]\n\ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$info(Username)\ eq\ \"root\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ dir\ \"/var/lib/installjammer\"\n\ \ \ \ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ dir\ \"\[::InstallJammer::HomeDir\]/.installjammerinfo\"\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ set\ dir\ \[file\ join\ \$dir\ \$info(ApplicationID)\]\n\n\ \ \ \ \ \ \ \ set\ info(InstallInfoDir)\ \[Normalize\ \$dir\]\n\ \ \ \ \}\n\n\ \ \ \ if\ \{\$create\ &&\ !\[file\ exists\ \$info(InstallInfoDir)\]\}\ \{\n\ \ \ \ \ \ \ \ ::InstallJammer::CreateDir\ \$info(InstallInfoDir)\ 0\n\ \ \ \ \ \ \ \ if\ \{\$conf(windows)\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ file\ attributes\ \[file\ dirname\ \$info(InstallInfoDir)\]\ -hidden\ 1\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ return\ \$info(InstallInfoDir)\n\}\n\nproc\ ::InstallJammer::InstallInfoDir\ \{\ \{file\ \"\"\}\ \}\ \{\n\ \ \ \ set\ dir\ \[::InstallJammer::GetInstallInfoDir\ 1\]\n\ \ \ \ if\ \{\[string\ length\ \$file\]\}\ \{\ append\ dir\ /\$file\ \}\n\ \ \ \ return\ \$dir\n\}\n\nproc\ ::InstallJammer::SetPermissions\ \{\ file\ perm\ \}\ \{\n\ \ \ \ if\ \{!\[string\ length\ \$perm\]\}\ \{\ return\ \}\n\n\ \ \ \ if\ \{\$::tcl_platform(platform)\ eq\ \"windows\"\}\ \{\n\tif\ \{\[string\ length\ \$perm\]\ >\ 4\}\ \{\ return\ \}\n\tlassign\ \[split\ \$perm\ \"\"\]\ a\ h\ r\ s\n\tfile\ attributes\ \$file\ -archive\ \$a\ -hidden\ \$h\ -readonly\ \$r\ -system\ \$s\n\treturn\n\ \ \ \ \}\n\ \ \ \ file\ attributes\ \$file\ -permissions\ \$perm\n\}\n\nproc\ ::InstallJammer::WriteDoneFile\ \{\ \{dir\ \"\"\}\ \}\ \{\n\ \ \ \ if\ \{!\[string\ length\ \$dir\]\}\ \{\ set\ dir\ \[file\ dirname\ \[info\ nameofexe\]\]\ \}\n\ \ \ \ close\ \[open\ \[file\ join\ \$dir\ .done\]\ w\]\n\}\n\n##\ This\ proc\ attempts\ to\ find\ any\ InstallJammer\ temporary\ directories\ laying\n##\ around\ and\ clean\ them\ up.\ \ If\ a\ file\ called\ .done\ is\ in\ the\ directory,\n##\ we\ know\ the\ InstallJammer\ program\ using\ that\ directory\ has\ finished\ with\ it,\n##\ and\ it's\ ok\ to\ remove.\nproc\ ::InstallJammer::CleanupTmpDirs\ \{\}\ \{\n\ \ \ \ if\ \{\[info\ exists\ ::conf(debugging)\]\ &&\ \$::conf(debugging)\}\ \{\ return\ \}\n\n\ \ \ \ set\ tmp\ \[file\ dirname\ \[TmpDir\]\]\n\ \ \ \ foreach\ dir\ \[glob\ -nocomplain\ -type\ d\ -dir\ \$tmp\ ijtmp_*\]\ \{\n\tif\ \{!\[DirIsEmpty\ \$dir\]\}\ \{\n\t\ \ \ \ if\ \{!\[file\ exists\ \[file\ join\ \$dir\ .done\]\]\}\ \{\ continue\ \}\n\t\}\n\tcatch\ \{\ file\ delete\ -force\ \$dir\ \}\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::EvalCondition\ \{\ condition\ \}\ \{\n\ \ \ \ if\ \{\[string\ is\ true\ \ \$condition\]\}\ \{\ return\ 1\ \}\n\ \ \ \ if\ \{\[string\ is\ false\ \$condition\]\}\ \{\ return\ 0\ \}\n\n\ \ \ \ set\ test\ \[::InstallJammer::SubstForEval\ \$condition\]\n\n\ \ \ \ if\ \{!\[string\ length\ \$test\]\}\ \{\ return\ 1\ \}\n\ \ \ \ if\ \{\[catch\ \{expr\ \[subst\ \$test\]\}\ result\]\}\ \{\n\ \ \ \ \ \ \ \ return\ -code\ error\ \"Error\ in\ condition\ '\$condition':\ \$result\"\n\ \ \ \ \}\n\ \ \ \ return\ \$result\n\}\n\nproc\ ::InstallJammer::HomeDir\ \{\}\ \{\n\ \ \ \ return\ \[file\ normalize\ ~\]\n\}\n\nproc\ ::InstallJammer::PauseInstall\ \{\}\ \{\n\ \ \ \ global\ conf\n\ \ \ \ if\ \{\[info\ exists\ conf(pause)\]\}\ \{\ close\ \[open\ \$conf(pause)\ w\]\ \}\n\}\n\nproc\ ::InstallJammer::ContinueInstall\ \{\}\ \{\n\ \ \ \ global\ conf\n\ \ \ \ if\ \{\[info\ exists\ conf(pause)\]\}\ \{\ file\ delete\ \$conf(pause)\ \}\n\}\n\nproc\ ::InstallJammer::StopInstall\ \{\}\ \{\n\ \ \ \ global\ conf\n\ \ \ \ global\ info\n\ \ \ \ if\ \{\[info\ exists\ conf(stop)\]\}\ \{\n\ \ \ \ \ \ \ \ close\ \[open\ \$conf(stop)\ w\]\n\ \ \ \ \ \ \ \ set\ info(InstallStopped)\ 1\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::PauseCheck\ \{\}\ \{\n\ \ \ \ global\ conf\n\ \ \ \ global\ info\n\n\ \ \ \ while\ \{\[file\ exists\ \$conf(pause)\]\}\ \{\n\tif\ \{\[file\ exists\ \$conf(stop)\]\}\ \{\n\t\ \ \ \ set\ info(InstallStopped)\ 1\n\ \ \ \ \ \ \ \ \ \ \ \ return\ 0\n\t\}\n\tafter\ 500\n\ \ \ \ \}\n\n\ \ \ \ return\ 1\n\}\n\nproc\ ::InstallJammer::UninstallFile\ \{file\}\ \{\n\ \ \ \ file\ delete\ -force\ \$file\n\}\n\nproc\ ::InstallJammer::UninstallDirectory\ \{\ dir\ \{force\ \"\"\}\ \}\ \{\n\ \ \ \ file\ delete\ \$force\ \$dir\n\}\n\n##\ Uninstall\ a\ registry\ key.\ \ If\ value\ is\ specified,\ we\ only\ want\ to\ delete\n##\ that\ value\ from\ the\ registry\ key.\ \ If,\ once\ the\ value\ has\ been\ deleted,\n##\ the\ registry\ key\ is\ empty,\ we\ will\ delete\ that\ as\ well.\nproc\ ::InstallJammer::UninstallRegistryKey\ \{key\ \{value\ \"\"\}\}\ \{\n\ \ \ \ if\ \{!\[lempty\ \$value\]\}\ \{\n\tcatch\ \{\ registry\ delete\ \$key\ \$value\ \}\n\tif\ \{\[catch\ \{\ registry\ keys\ \$key\ \}\ keys\]\}\ \{\ return\ \}\n\tif\ \{\[catch\ \{\ registry\ values\ \$key\ \}\ values\]\}\ \{\ return\ \}\n\tif\ \{\[lempty\ \$keys\]\ &&\ \[lempty\ \$values\]\}\ \{\n\t\ \ \ \ UninstallRegistryKey\ \$key\n\t\}\n\ \ \ \ \}\ else\ \{\n\tcatch\ \{\ registry\ delete\ \$key\ \}\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::LogDir\ \{dir\}\ \{\n\ \ \ \ global\ info\n\ \ \ \ set\ dir\ \[Normalize\ \$dir\]\n\ \ \ \ if\ \{!\[string\ match\ \$info(InstallInfoDir)*\ \$dir\]\n\ \ \ \ \ \ \ \ &&\ !\[string\ match\ \$info(Temp)*\ \$dir\]\}\ \{\n\ \ \ \ \ \ \ \ ::InstallJammer::InstallLog\ \":DIR\ \[list\ \$dir\]\"\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::LogFile\ \{file\}\ \{\n\ \ \ \ global\ info\n\ \ \ \ set\ file\ \[Normalize\ \$file\]\n\ \ \ \ if\ \{!\[string\ match\ \$info(InstallInfoDir)*\ \$file\]\n\ \ \ \ \ \ \ \ &&\ !\[string\ match\ \$info(Temp)*\ \$file\]\}\ \{\n\ \ \ \ \ \ \ \ ::InstallJammer::InstallLog\ \":FILE\ \[list\ \$file\]\"\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::SetVersionInfo\ \{\ file\ \{version\ \"\"\}\ \}\ \{\n\ \ \ \ global\ info\n\ \ \ \ global\ versions\n\ \ \ \ if\ \{!\[string\ length\ \$version\]\}\ \{\ set\ version\ \$info(InstallVersion)\ \}\n\ \ \ \ set\ versions(\$file)\ \$version\n\}\n\nproc\ ::InstallJammer::MessageBox\ \{\ args\ \}\ \{\n\ \ \ \ global\ conf\n\ \ \ \ global\ widg\n\n\ \ \ \ set\ win\ \ .__message_box\n\ \ \ \ set\ args\ \[linsert\ \$args\ 0\ -type\ ok\ -buttonwidth\ 12\]\n\ \ \ \ if\ \{\[info\ exists\ conf(cmdline)\]\ &&\ \$conf(cmdline)\}\ \{\n\ \ \ \ \ \ \ \ set\ usenative\ 1\n\ \ \ \ \ \ \ \ set\ args\ \[linsert\ \$args\ 0\ -title\ \"InstallJammer\"\]\n\ \ \ \ \}\ elseif\ \{\[info\ exists\ widg(InstallJammer)\]\}\ \{\n\ \ \ \ \ \ \ \ set\ usenative\ 1\n\ \ \ \ \ \ \ \ set\ win\ \ \[::InstallJammer::TopName\ \$win\]\n\ \ \ \ \ \ \ \ set\ args\ \[linsert\ \$args\ 0\ -title\ \"InstallJammer\"\]\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ set\ usenative\ 0\n\ \ \ \ \ \ \ \ set\ parent\ \[::InstallJammer::TransientParent\]\n\ \ \ \ \ \ \ \ set\ args\ \[linsert\ \$args\ 0\ -usenative\ \$usenative\ -parent\ \$parent\]\n\ \ \ \ \}\n\n\ \ \ \ if\ \{!\$usenative\ &&\ !\[string\ length\ \$parent\]\}\ \{\ set\ _args(-transient)\ 0\ \}\n\n\ \ \ \ array\ set\ _args\ \$args\n\ \ \ \ set\ type\ \$_args(-type)\n\n\ \ \ \ if\ \{!\$usenative\ &&\ \$type\ ne\ \"user\"\}\ \{\n\ \ \ \ \ \ \ \ foreach\ button\ \{Abort\ Retry\ Ignore\ OK\ Yes\ No\ Cancel\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ lbutton\ \[string\ tolower\ \$button\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ first\ \$lbutton\ \$_args(-type)\]\ >\ -1\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ lappend\ buttons\ \$lbutton\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ lappend\ _args(-buttons)\ \[::InstallJammer::SubstText\ <%\$button%>\]\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ set\ _args(-type)\ user\n\ \ \ \ \}\n\n\ \ \ \ set\ result\ \[eval\ \[list\ MessageDlg\ \$win\]\ \[array\ get\ _args\]\]\n\n\ \ \ \ if\ \{!\$usenative\ &&\ \$type\ ne\ \"user\"\}\ \{\ return\ \[lindex\ \$buttons\ \$result\]\ \}\n\ \ \ \ return\ \$result\n\}\n\nproc\ ::InstallJammer::Message\ \{\ args\ \}\ \{\n\ \ \ \ set\ title\ \"InstallJammer\"\n\ \ \ \ if\ \{\[info\ exists\ ::tk_patchLevel\]\}\ \{\n\ \ \ \ \ \ \ \ eval\ \[list\ ::InstallJammer::MessageBox\ -title\ \$title\]\ \$args\n\ \ \ \ \}\ else\ \{\n\tset\ data(-title)\ \$title\n\tarray\ set\ data\ \$args\n\tif\ \{!\[info\ exists\ data(-message)\]\}\ \{\ return\ \}\n\tputs\ stdout\ \"\$data(-title):\ \$data(-message)\"\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::HandleThreadError\ \{\ tid\ errorMsg\ \}\ \{\n\ \ \ \ set\ message\ \"Error\ in\ thread\ \$tid:\ \$errorMsg\"\n\ \ \ \ ::InstallJammer::MessageBox\ -message\ \$message\n\}\n\nproc\ ::InstallJammer::ChooseDirectory\ \{\ args\ \}\ \{\n\ \ \ \ global\ conf\n\n\ \ \ \ if\ \{0\ &&\ \$conf(windows)\}\ \{\n\ \ \ \ \ \ \ \ array\ set\ _args\ \$args\n\ \ \ \ \ \ \ \ if\ \{\[info\ exists\ _args(-message)\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ _args(-title)\ \$_args(-message)\n\ \ \ \ \ \ \ \ \ \ \ \ unset\ _args(-message)\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ set\ dir\ \[eval\ tk_chooseDirectory\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ \[list\ -parent\ \[lindex\ \$conf(ParentWindow)\ 0\]\]\ \[array\ get\ _args\]\]\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ if\ \{\[llength\ \$conf(ParentWindow)\]\ >\ 1\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ wm\ withdraw\ \[lindex\ \$conf(ParentWindow)\ end\]\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ set\ dir\ \[eval\ ::ChooseDirectory\ .__choose_directory\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ \[list\ -parent\ \[::InstallJammer::TransientParent\]\]\ \$args\]\n\n\ \ \ \ \ \ \ \ if\ \{\[llength\ \$conf(ParentWindow)\]\ >\ 1\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ wm\ deiconify\ \[lindex\ \$conf(ParentWindow)\ end\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ return\ \$dir\n\}\n\nproc\ ::InstallJammer::CommandExists\ \{\ proc\ \}\ \{\n\ \ \ \ return\ \[string\ length\ \[info\ commands\ \$proc\]\]\n\}\n\nproc\ ::InstallJammer::uuid\ \{\}\ \{\n\ \ \ \ global\ conf\n\n\ \ \ \ if\ \{\$conf(windows)\}\ \{\ return\ \[lindex\ \[::Windows::guid\]\ 0\]\ \}\n\n\ \ \ \ set\ fp\ \[open\ /dev/urandom\]\n\ \ \ \ fconfigure\ \$fp\ -translation\ binary\n\ \ \ \ foreach\ x\ \{4\ 2\ 2\ 6\}\ \{\n\ \ \ \ \ \ \ \ binary\ scan\ \[read\ \$fp\ \$x\]\ h*\ hex\n\ \ \ \ \ \ \ \ lappend\ list\ \$hex\n\ \ \ \ \}\n\ \ \ \ close\ \$fp\n\ \ \ \ return\ \[string\ toupper\ \[join\ \$list\ -\]\]\n\}\n\nproc\ ::InstallJammer::guid\ \{\}\ \{\n\ \ \ \ global\ conf\n\ \ \ \ if\ \{\$conf(windows)\}\ \{\ return\ \[::Windows::guid\]\ \}\n\ \ \ \ return\ \\\{\[string\ toupper\ \[::InstallJammer::uuid\]\]\\\}\n\}\n\nproc\ ::InstallJammer::ObjExists\ \{\ obj\ \}\ \{\n\ \ \ \ return\ \[info\ exists\ ::InstallJammer::ObjMap(\[namespace\ tail\ \$obj\])\]\n\}\n\nproc\ ::InstallJammer::ReadMessageCatalog\ \{\ catalog\ \}\ \{\n\ \ \ \ eval\ \[read_file\ \[file\ join\ \$::installkit::root\ catalogs\ \$catalog\]\]\n\}\n\nproc\ ::InstallJammer::Wrap\ \{\ args\ \}\ \{\n\ \ \ \ global\ conf\n\ \ \ \ global\ info\n\n\ \ \ \ set\ include\ 1\n\ \ \ \ if\ \{\[set\ x\ \[lsearch\ -exact\ \$args\ -noinstall\]\]\ >\ -1\}\ \{\n\ \ \ \ \ \ \ \ set\ include\ 0\n\ \ \ \ \ \ \ \ set\ args\ \[lreplace\ \$args\ \$x\ \$x\]\n\ \ \ \ \}\n\n\ \ \ \ if\ \{\$include\}\ \{\n\ \ \ \ \ \ \ \ if\ \{\$::tcl_platform(platform)\ eq\ \"windows\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ wintcl\ \[file\ join\ \$::installkit::root\ lib\ Wintcl\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ args\ \[linsert\ \$args\ 0\ -package\ \$wintcl\]\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ set\ pkgdir\ \[file\ join\ \$::installkit::root\ lib\ InstallJammer\]\n\ \ \ \ \ \ \ \ set\ args\ \[linsert\ \$args\ 0\ -package\ \$pkgdir\]\n\n\ \ \ \ \ \ \ \ set\ pkgdir\ \[file\ join\ \$::installkit::root\ lib\ \$info(Platform)\]\n\ \ \ \ \ \ \ \ if\ \{\[file\ exists\ \$pkgdir\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ args\ \[linsert\ \$args\ 0\ -package\ \$pkgdir\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ eval\ ::installkit::wrap\ \$args\n\}\n\nproc\ ::InstallJammer::Grab\ \{\ command\ args\ \}\ \{\n\ \ \ \ variable\ GrabStack\n\n\ \ \ \ if\ \{!\[info\ exists\ GrabStack\]\}\ \{\ set\ GrabStack\ \[list\]\ \}\n\n\ \ \ \ switch\ --\ \$command\ \{\n\ \ \ \ \ \ \ \ \"current\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ return\ \[lindex\ \$GrabStack\ end\]\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \"stack\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ return\ \$GrabStack\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \"release\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ window\ \[lindex\ \$args\ 0\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ search\ \[lsearch\ -exact\ \$GrabStack\ \$window\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$search\ <\ 0\}\ \{\ return\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$search\ !=\ \[expr\ \{\[llength\ \$GrabStack\]\ -\ 1\}\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ -code\ error\ \"\$window\ is\ not\ last\ in\ the\ grab\ stack.\"\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ grab\ release\ \$window\n\ \ \ \ \ \ \ \ \ \ \ \ set\ GrabStack\ \[lreplace\ \$GrabStack\ end\ end\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[llength\ \$GrabStack\]\}\ \{\ grab\ \[lindex\ \$GrabStack\ end\]\ \}\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \"set\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ window\ \[lindex\ \$args\ 0\]\n\ \ \ \ \ \ \ \ \ \ \ \ grab\ \$window\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ GrabStack\ \$window\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ default\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ grab\ \$command\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ GrabStack\ \$command\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ return\n\}\n\nproc\ ::InstallJammer::HasKDEDesktop\ \{\}\ \{\n\ \ \ \ global\ info\n\n\ \ \ \ set\ home\ \[::InstallJammer::HomeDir\]\n\ \ \ \ set\ kde\ \ \[file\ join\ \$home\ .kde\]\n\n\ \ \ \ if\ \{!\[file\ exists\ \$kde\]\}\ \{\ return\ 0\ \}\n\n\ \ \ \ if\ \{!\[info\ exists\ info(KDEDesktop)\]\ ||\ \[lempty\ \$info(KDEDesktop)\]\}\ \{\n\tset\ globals\ \[file\ join\ \$kde\ share\ config\ kdeglobals\]\n\tset\ desktop\ \[file\ join\ \$home\ Desktop\]\n\tif\ \{\[catch\ \{open\ \$globals\}\ fp\]\}\ \{\ return\ 0\ \}\n\twhile\ \{\[gets\ \$fp\ line\]\ !=\ -1\}\ \{\n\t\ \ \ \ if\ \{\[regexp\ \{^Desktop=(\[^\\n\].*)\\n\}\ \$line\\n\ trash\ desktop\]\}\ \{\n\t\tregsub\ -all\ \{\\\$(\[A-Za-z0-9\]+)\}\ \$desktop\ \{\$::env(\\1)\}\ desktop\n\t\tbreak\n\t\ \ \ \ \}\n\t\}\n\tclose\ \$fp\n\tset\ info(KDEDesktop)\ \$desktop\n\ \ \ \ \}\n\n\ \ \ \ return\ \[file\ exists\ \$info(KDEDesktop)\]\n\}\n\nproc\ ::InstallJammer::HasGnomeDesktop\ \{\}\ \{\n\ \ \ \ global\ info\n\n\ \ \ \ set\ home\ \[::InstallJammer::HomeDir\]\n\n\ \ \ \ foreach\ dir\ \[list\ .gnome-desktop\ Desktop\]\ \{\n\ \ \ \ \ \ \ \ set\ desktop\ \[file\ join\ \$home\ \$dir\]\n\ \ \ \ \ \ \ \ if\ \{\[file\ exists\ \$desktop\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ info(GnomeDesktop)\ \$desktop\n\ \ \ \ \ \ \ \ \ \ \ \ break\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ if\ \{\[info\ exists\ info(GnomeDesktop)\]\ &&\ \[file\ exists\ \$info(GnomeDesktop)\]\}\ \{\n\ \ \ \ \ \ \ \ return\ 1\n\ \ \ \ \}\n\ \ \ \ return\ 0\n\}\n\nproc\ ::InstallJammer::GetDesktopEnvironment\ \{\}\ \{\n\ \ \ \ global\ env\n\n\ \ \ \ ##\ KDE\n\ \ \ \ if\ \{\[info\ exists\ env(DESKTOP)\]\ &&\ \$env(DESKTOP)\ eq\ \"kde\"\}\ \{\ return\ KDE\ \}\n\ \ \ \ if\ \{\[info\ exists\ env(KDE_FULL_SESSION)\]\}\ \{\ return\ KDE\ \}\n\n\ \ \ \ ##\ Gnome\n\ \ \ \ if\ \{\[info\ exists\ env(GNOME_DESKTOP_SESSION_ID)\]\}\ \{\ return\ Gnome\ \}\n\n\ \ \ \ if\ \{\[info\ exists\ env(DESKTOP_SESSION)\]\}\ \{\n\ \ \ \ \ \ \ \ switch\ -glob\ --\ \$env(DESKTOP_SESSION)\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \"*KDE*\"\ \ \ \{\ return\ KDE\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \"*GNOME*\"\ \{\ return\ Gnome\ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ return\ \"Unknown\"\n\}\n\nproc\ ::InstallJammer::GetLinuxDistribution\ \{\}\ \{\n\ \ \ \ set\ lsb_release\ \[which\ lsb_release\]\n\ \ \ \ if\ \{\[file\ executable\ \$lsb_release\]\}\ \{\n\ \ \ \ \ \ \ \ if\ \{!\[catch\ \{\ exec\ \$lsb_release\ -i\ -s\ \}\ distrib\]\}\ \{\ return\ \$distrib\ \}\n\ \ \ \ \}\n\n\ \ \ \ foreach\ lsb_release\ \[list\ /etc/lsb-release\ /etc/lsb_release\]\ \{\n\tif\ \{\[file\ readable\ \$lsb_release\]\}\ \{\n\n\t\}\n\ \ \ \ \}\n\n\ \ \ \ set\ check\ \{\n\t/etc/mandrake-release\ \ \ \ Mandrake\n\t/etc/fedora-release\ \ \ \ \ \ Fedora\n\t/etc/SuSE-release\ \ \ \ \ \ \ \ SuSE\n\t/etc/debian_version\ \ \ \ \ \ Debian\n\t/etc/gentoo-release\ \ \ \ \ \ Gentoo\n\t/etc/slackware-version\ \ \ Slackware\n\t/etc/turbolinux-release\ \ TurboLinux\n\t/etc/yellowdog-release\ \ \ YellowDog\n\t/etc/connectiva-release\ \ Connectiva\n\t/etc/redhat-release\ \ \ \ \ \ Redhat\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::GetFreeDiskSpace\ \{\ dir\ \}\ \{\n\ \ \ \ global\ conf\n\n\ \ \ \ if\ \{\$conf(windows)\}\ \{\n\ \ \ \ \ \ \ \ return\ \[::Windows::drive\ freespace\ \[lindex\ \[file\ split\ \$dir\]\ 0\]\]\n\ \ \ \ \}\n\n\ \ \ \ set\ df\ \[which\ df\]\n\ \ \ \ if\ \{\[file\ exists\ \$df\]\}\ \{\n\ \ \ \ \ \ \ \ catch\ \{\ exec\ \$df\ -k\ \$dir\ \}\ output\n\n\ \ \ \ \ \ \ \ set\ line\ \[join\ \[lrange\ \[split\ \$output\ \\n\]\ 1\ end\]\ \"\ \"\]\n\ \ \ \ \ \ \ \ if\ \{!\[catch\ \{\ expr\ \{\[lindex\ \$line\ 3\]\ *\ 1024.0\}\ \}\ avail\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ return\ \$avail\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ return\ -1\n\}\n\nproc\ ::InstallJammer::FormatDiskSpace\ \{\ space\ \}\ \{\n\ \ \ \ if\ \{\$space\ <\ 1048576\}\ \{\n\ \ \ \ \ \ \ \ return\ \[format\ \"%2.2f\ KB\"\ \[expr\ \{\$space\ /\ 1024.0\}\]\]\n\ \ \ \ \}\n\ \ \ \ if\ \{\$space\ <\ 1073741824\}\ \{\n\ \ \ \ \ \ \ \ return\ \[format\ \"%2.2f\ MB\"\ \[expr\ \{\$space\ /\ 1048576.0\}\]\]\n\ \ \ \ \}\n\ \ \ \ return\ \[format\ \"%2.2f\ GB\"\ \[expr\ \{\$space\ /\ 1073741824.0\}\]\]\n\}\n\nproc\ ::InstallJammer::unpack\ \{\ src\ dest\ \{permissions\ \"\"\}\ \}\ \{\n\ \ \ \ if\ \{!\[string\ length\ \$permissions\]\}\ \{\ set\ permissions\ \"0666\"\ \}\n\n\ \ \ \ #\ Extract\ the\ file\ and\ copy\ it\ to\ its\ location.\n\ \ \ \ set\ fin\ \[open\ \$src\ r\]\n\ \ \ \ if\ \{\[catch\ \{open\ \$dest\ w\ \$permissions\}\ fout\]\}\ \{\n\tclose\ \$fin\n\treturn\ -code\ error\ \$fout\n\ \ \ \ \}\n\n\ \ \ \ fconfigure\ \$fin\ \ -translation\ binary\n\ \ \ \ fconfigure\ \$fout\ -translation\ binary\n\n\ \ \ \ fcopy\ \$fin\ \$fout\n\n\ \ \ \ close\ \$fin\n\ \ \ \ close\ \$fout\n\}\n\nproc\ ::InstallJammer::GetFilesForPattern\ \{\ patternString\ args\ \}\ \{\n\ \ \ \ set\ relative\ \ \ 1\n\ \ \ \ set\ recursive\ \ 0\n\ \ \ \ set\ files\ \ \ \ \ \ \[list\]\n\ \ \ \ set\ patterns\ \ \ \[list\]\n\ \ \ \ set\ installdir\ \[::InstallJammer::SubstText\ <%InstallDir%>\]\n\n\ \ \ \ array\ set\ _args\ \$args\n\ \ \ \ if\ \{\[info\ exists\ _args(-recursive)\]\}\ \{\n\ \ \ \ \ \ \ \ set\ recursive\ 1\n\ \ \ \ \ \ \ \ unset\ _args(-recursive)\n\ \ \ \ \}\n\ \ \ \ set\ args\ \[array\ get\ _args\]\n\n\ \ \ \ foreach\ pattern\ \[split\ \$patternString\ \\\;\]\ \{\n\ \ \ \ \ \ \ \ set\ pattern\ \[string\ trim\ \[::InstallJammer::SubstText\ \$pattern\]\]\n\ \ \ \ \ \ \ \ if\ \{\[file\ pathtype\ \$pattern\]\ ne\ \"relative\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ relative\ 0\n\ \ \ \ \ \ \ \ \ \ \ \ set\ pattern\ \[::InstallJammer::Normalize\ \$pattern\]\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ lappend\ patterns\ \$pattern\n\ \ \ \ \}\n\n\ \ \ \ if\ \{!\[llength\ \$patterns\]\}\ \{\ return\ \}\n\n\ \ \ \ if\ \{\$relative\}\ \{\n\ \ \ \ \ \ \ \ ##\ All\ of\ our\ patterns\ are\ relative,\ so\ we\ can\ do\ a\ single,\ quick\n\ \ \ \ \ \ \ \ ##\ glob\ to\ find\ everything\ relative\ to\ the\ <%InstallDir%>.\n\ \ \ \ \ \ \ \ set\ opts\ \$args\n\ \ \ \ \ \ \ \ lappend\ opts\ -dir\ \$installdir\n\n\ \ \ \ \ \ \ \ set\ files\ \[eval\ glob\ -nocomplain\ \$opts\ \$patterns\]\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ foreach\ pattern\ \$patterns\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ opts\ \$args\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[file\ pathtype\ \$pattern\]\ eq\ \"relative\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ lappend\ opts\ -dir\ \$installdir\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ eval\ lappend\ files\ \[eval\ glob\ -nocomplain\ \$opts\ \[list\ \$pattern\]\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ return\ \$files\n\}\n\npackage\ require\ Itcl\n\n::itcl::class\ Object\ \{\n\ \ \ \ constructor\ \{args\}\ \{\n\ \ \ \ \ \ \ \ eval\ configure\ \$args\n\ \ \ \ \ \ \ \ set\ ::InstallJammer::ObjMap(\[namespace\ tail\ \$this\])\ \[incr\ objc\]\n\ \ \ \ \}\n\n\ \ \ \ destructor\ \{\n\ \ \ \ \ \ \ \ unset\ ::InstallJammer::ObjMap(\[namespace\ tail\ \$this\])\n\ \ \ \ \}\n\n\ \ \ \ method\ destroy\ \{\}\ \{\n\ \ \ \ \ \ \ \ ::itcl::delete\ object\ \$this\n\ \ \ \ \}\n\n\ \ \ \ method\ cfgvar\ \{\ args\ \}\ \{\n\ \ \ \ \ \ \ \ if\ \{\[llength\ \$args\]\ ==\ 2\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ configure\ -\[lindex\ \$args\ 0\]\ \[lindex\ \$args\ 1\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ return\ \[cget\ -\[lindex\ \$args\ 0\]\]\n\ \ \ \ \}\n\n\ \ \ \ method\ serialize\ \{\}\ \{\n\ \ \ \ \ \ \ \ set\ return\ \[list\]\n\ \ \ \ \ \ \ \ foreach\ list\ \[configure\]\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ opt\ \[lindex\ \$list\ 0\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ def\ \[lindex\ \$list\ end-1\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ val\ \[lindex\ \$list\ end\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$def\ ==\ \$val\}\ \{\ continue\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ return\ \$opt\ \$val\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ return\ \$return\n\ \ \ \ \}\n\n\ \ \ \ common\ objc\ 0\n\}\ \;\ ##\ ::itcl::class\ Object\n\n::itcl::class\ TreeObject\ \{\n\ \ \ \ inherit\ Object\n\n\ \ \ \ constructor\ \{\ args\ \}\ \{\n\ \ \ \ \ \ \ \ set\ id\ \[namespace\ tail\ \$this\]\n\ \ \ \ \ \ \ \ eval\ configure\ \$args\n\ \ \ \ \ \ \ \ if\ \{!\$temp\ &&\ \[string\ length\ \$parent\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \$parent\ children\ insert\ \$index\ \$id\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ destructor\ \{\n\ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$parent\]\}\ \{\ \$parent\ children\ remove\ \$id\ \}\n\n\ \ \ \ \ \ \ \ foreach\ child\ \$children\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \$child\ destroy\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ CleanupAlias\n\ \ \ \ \}\n\n\ \ \ \ method\ serialize\ \{\}\ \{\n\ \ \ \ \ \ \ \ set\ return\ \[list\]\n\ \ \ \ \ \ \ \ foreach\ list\ \[configure\]\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ opt\ \[lindex\ \$list\ 0\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$opt\ eq\ \"-id\"\ ||\ \$opt\ eq\ \"-index\"\}\ \{\ continue\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ set\ def\ \[lindex\ \$list\ end-1\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ val\ \[lindex\ \$list\ end\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$opt\ eq\ \"-name\"\ &&\ \$val\ eq\ \[string\ tolower\ \$id\]\}\ \{\ continue\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$def\ ==\ \$val\}\ \{\ continue\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ return\ \$opt\ \$val\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ return\ \$return\n\ \ \ \ \}\n\n\ \ \ \ method\ CleanupAlias\ \{\}\ \{\n\ \ \ \ \ \ \ \ variable\ ::InstallJammer::aliases\n\ \ \ \ \ \ \ \ variable\ ::InstallJammer::aliasmap\n\n\ \ \ \ \ \ \ \ if\ \{\[info\ exists\ aliasmap(\$id)\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ unset\ -nocomplain\ aliases(\$aliasmap(\$id))\n\ \ \ \ \ \ \ \ \ \ \ \ unset\ aliasmap(\$id)\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ protected\ method\ recursive\ \{\ idlist\ \}\ \{\n\ \ \ \ \ \ \ \ set\ list\ \[list\]\n\ \ \ \ \ \ \ \ for\ \{set\ i\ 0\}\ \{\$i\ <\ \[llength\ \$idlist\]\}\ \{incr\ i\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ item\ \[lindex\ \$idlist\ \$i\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{!\[string\ length\ \$item\]\}\ \{\ break\ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ list\ \$item\n\ \ \ \ \ \ \ \ \ \ \ \ set\ childids\ \[\$item\ children\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[llength\ \$childids\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ x\ \[expr\ \{\$i\ +\ 1\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ idlist\ \[eval\ linsert\ \[list\ \$idlist\]\ \$x\ \$childids\]\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ return\ \$list\n\ \ \ \ \}\n\n\ \ \ \ method\ parent\ \{\ args\ \}\ \{\n\ \ \ \ \ \ \ \ if\ \{\[lempty\ \$args\]\}\ \{\ return\ \$parent\ \}\n\n\ \ \ \ \ \ \ \ if\ \{!\[string\ equal\ \$args\ \"recursive\"\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ return\ \[set\ parent\ \[lindex\ \$args\ 0\]\]\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ set\ x\ \ \ \ \$parent\n\ \ \ \ \ \ \ \ set\ list\ \[list\]\n\ \ \ \ \ \ \ \ while\ \{\[string\ length\ \$x\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ list\ \[linsert\ \$list\ 0\ \$x\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ x\ \[\$x\ parent\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ return\ \$list\n\ \ \ \ \}\n\n\ \ \ \ method\ reparent\ \{\ newParent\ \}\ \{\n\ \ \ \ \ \ \ \ ##\ If\ this\ is\ already\ our\ parent,\ don't\ do\ anything.\n\ \ \ \ \ \ \ \ if\ \{\[string\ equal\ \$parent\ \$newParent\]\}\ \{\ return\ \}\n\n\ \ \ \ \ \ \ \ ##\ If\ we\ have\ an\ old\ parent,\ remove\ us\ from\ their\ children.\n\ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$parent\]\}\ \{\ \$parent\ children\ remove\ \$id\ \}\n\n\ \ \ \ \ \ \ \ ##\ Add\ ourselves\ to\ the\ new\ parent.\n\ \ \ \ \ \ \ \ set\ parent\ \$newParent\n\ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$parent\]\}\ \{\ \$parent\ children\ add\ \$id\ \}\n\ \ \ \ \}\n\n\ \ \ \ method\ children\ \{\ args\ \}\ \{\n\ \ \ \ \ \ \ \ if\ \{\[lempty\ \$args\]\}\ \{\ return\ \$children\ \}\n\n\ \ \ \ \ \ \ \ lassign\ \$args\ command\ obj\n\ \ \ \ \ \ \ \ switch\ --\ \$command\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \"add\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ children\ insert\ end\ \$obj\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \"index\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ \[lsearch\ -exact\ \$children\ \$obj\]\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \"insert\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ lassign\ \$args\ command\ index\ obj\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$index\ eq\ \"end\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ lappend\ children\ \$obj\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ children\ \[linsert\ \$children\ \$index\ \$obj\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \"remove\"\ -\ \"delete\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ children\ \[lremove\ \$children\ \$obj\]\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \"reorder\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[llength\ \$obj\]\}\ \{\ set\ children\ \$obj\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \"recursive\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ \[recursive\ \$children\]\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ method\ is\ \{\ args\ \}\ \{\n\ \ \ \ \ \ \ \ if\ \{\[llength\ \$args\]\ ==\ 1\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ return\ \[string\ equal\ \$type\ \[lindex\ \$args\ 0\]\]\n\ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ return\ \[expr\ \{\[lsearch\ -exact\ \$args\ \$type\]\ >\ -1\}\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ method\ index\ \{\}\ \{\n\ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$parent\]\}\ \{\ return\ \[\$parent\ children\ index\ \$id\]\ \}\n\ \ \ \ \}\n\n\ \ \ \ method\ id\ \ \ \ \ \ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ id\ \ \ \ \ \ \ \ \$args\ \}\n\ \ \ \ method\ name\ \ \ \ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ name\ \ \ \ \ \ \$args\ \}\n\ \ \ \ method\ type\ \ \ \ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ type\ \ \ \ \ \ \$args\ \}\n\ \ \ \ method\ alias\ \ \ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ alias\ \ \ \ \ \$args\ \}\n\ \ \ \ method\ active\ \ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ active\ \ \ \ \$args\ \}\n\ \ \ \ method\ comment\ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ comment\ \ \ \$args\ \}\n\ \ \ \ method\ platforms\ \{\ args\ \}\ \{\ eval\ cfgvar\ platforms\ \$args\ \}\n\n\ \ \ \ public\ variable\ id\ \ \ \ \ \ \"\"\n\ \ \ \ public\ variable\ temp\ \ \ \ 0\n\ \ \ \ public\ variable\ name\ \ \ \ \"\"\n\ \ \ \ public\ variable\ type\ \ \ \ \"\"\n\ \ \ \ public\ variable\ index\ \ \ \"end\"\n\ \ \ \ public\ variable\ active\ \ 1\n\ \ \ \ public\ variable\ parent\ \ \"\"\n\ \ \ \ public\ variable\ comment\ \"\"\n\n\ \ \ \ public\ variable\ platforms\ \[list\]\n\n\ \ \ \ protected\ variable\ children\ \[list\]\n\n\ \ \ \ private\ variable\ oldalias\ \"\"\n\ \ \ \ public\ \ variable\ alias\ \ \ \ \"\"\ \{\n\ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$oldalias\]\}\ \{\ CleanupAlias\ \}\n\ \ \ \ \ \ \ \ set\ oldalias\ \$alias\n\n\ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$alias\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ ::InstallJammer::aliases(\$alias)\ \$id\n\ \ \ \ \ \ \ \ \ \ \ \ set\ ::InstallJammer::aliasmap(\$id)\ \$alias\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\}\n\n::itcl::class\ InstallType\ \{\n\ \ \ \ inherit\ TreeObject\n\n\ \ \ \ constructor\ \{\ args\ \}\ \{\n\ \ \ \ \ \ \ \ eval\ configure\ \$args\n\ \ \ \ \}\ \{\n\ \ \ \ \ \ \ \ set\ type\ installtype\n\ \ \ \ \ \ \ \ eval\ configure\ \$args\n\ \ \ \ \}\n\n\ \ \ \ method\ widget\ \{\ args\ \}\ \{\}\n\ \ \ \ method\ setup\ \ \{\ args\ \}\ \{\ eval\ cfgvar\ setup\ \ \ \ \ \ \ \$args\ \}\n\n\ \ \ \ public\ variable\ setup\ \ \"\"\n\}\n\nitcl::class\ File\ \{\n\ \ \ \ inherit\ TreeObject\n\n\ \ \ \ constructor\ \{args\}\ \{\n\teval\ configure\ \$args\n\ \ \ \ \}\ \{\n\ \ \ \ \ \ \ \ ::set\ type\ file\n\ \ \ \ \ \ \ \ eval\ configure\ \$args\n\ \ \ \ \}\n\n\ \ \ \ method\ srcfile\ \{\}\ \{\n\treturn\ \[file\ join\ \$::conf(vfs)\ \$id\]\n\ \ \ \ \}\n\n\ \ \ \ method\ destfile\ \{\}\ \{\n\t::set\ dir\ \[::InstallJammer::SubstText\ \$directory\]\n\treturn\ \[file\ join\ \$dir\ \[file\ tail\ \$name\]\]\n\ \ \ \ \}\n\n\ \ \ \ method\ createdir\ \{\}\ \{\n\t::InstallJammer::CreateDir\ \[::InstallJammer::SubstText\ \$directory\]\n\ \ \ \ \}\n\n\ \ \ \ method\ install\ \{\}\ \{\n\tglobal\ conf\n\n\tif\ \{!\[::InstallJammer::PauseCheck\]\}\ \{\ return\ 0\ \}\n\n\ \ \ \ \ \ \ \ ::set\ dest\ \[install\$type\]\n\n\ \ \ \ \ \ \ \ if\ \{\$conf(windows)\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ ::InstallJammer::SetPermissions\ \$dest\ \$attributes\n\ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$type\ eq\ \"dir\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{!\[string\ length\ \$permissions\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ global\ info\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::set\ permissions\ \$info(DefaultDirectoryPermission)\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::InstallJammer::SetPermissions\ \$dest\ \$permissions\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ return\ 1\n\ \ \ \ \}\n\n\ \ \ \ method\ installdir\ \{\}\ \{\n\ \ \ \ \ \ \ \ createdir\n\ \ \ \ \}\n\n\ \ \ \ method\ installfile\ \{\ \{dest\ \"\"\}\ \{checkFileMethod\ 1\}\ \{logFile\ 1\}\ \}\ \{\n\tglobal\ conf\n\tglobal\ info\n\tglobal\ versions\n\n\tcreatedir\n\n\t::set\ doInstall\ 1\n\t::set\ src\ \[srcfile\]\n\ \ \ \ \ \ \ \ if\ \{!\[string\ length\ \$dest\]\}\ \{\ ::set\ dest\ \[destfile\]\ \}\n\n\ \ \ \ \ \ \ \ if\ \{!\[string\ length\ \$version\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ ::set\ version\ \$::info(InstallVersion)\n\ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ ::set\ version\ \[::InstallJammer::SubstText\ \$version\]\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ if\ \{\$checkFileMethod\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{!\[string\ length\ \$filemethod\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::set\ filemethod\ \[\$parent\ filemethod\]\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ switch\ --\ \$filemethod\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \"Never\ overwrite\ files\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ##\ We\ don't\ want\ to\ overwrite.\ \ If\ the\ file\ exists,\ skip\ it.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{!\[info\ exists\ exists\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::set\ exists\ \[file\ exists\ \$dest\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$exists\}\ \{\ ::set\ doInstall\ 0\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \"Update\ files\ with\ more\ recent\ dates\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ##\ We\ only\ want\ to\ overwrite\ if\ the\ file\ we\ have\ is\ newer\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ##\ than\ the\ one\ already\ installed.\ \ If\ the\ one\ we\ have\ is\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ##\ older,\ skip\ it.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{!\[info\ exists\ exists\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::set\ exists\ \[file\ exists\ \$dest\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$exists\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[file\ mtime\ \$dest\]\ >=\ \$mtime\}\ \{\ ::set\ doInstall\ 0\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \"Update\ files\ with\ a\ newer\ version\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ global\ info\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ##\ We\ want\ to\ overwrite\ the\ file\ if\ we\ have\ a\ newer\ version\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ##\ than\ the\ one\ stored.\ \ If\ there\ isn't\ one\ stored,\ we'll\ go\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ##\ ahead\ and\ store\ ours.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{!\[info\ exists\ exists\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::set\ exists\ \[file\ exists\ \$dest\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$exists\ &&\ \[info\ exists\ versions(\$dest)\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::set\ c\ \[package\ vcompare\ \$version\ \$versions(\$dest)\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$c\ ==\ 0\ ||\ \$c\ ==\ -1\}\ \{\ ::set\ doInstall\ 0\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \"Always\ overwrite\ files\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ##\ We\ want\ to\ always\ overwrite\ the\ file.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ##\ This\ is\ the\ default\ action,\ so\ we\ do\ nothing.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\n\t::set\ info(FileSize)\ \$size\n\tif\ \{!\$doInstall\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ ::set\ progress\ ::InstallJammer::IncrProgress\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[::InstallJammer::CommandExists\ \$progress\]\}\ \{\ \$progress\ \$size\ \}\n\t\ \ \ \ return\ \$dest\n\t\}\n\n\ \ \ \ \ \ \ \ if\ \{!\[string\ length\ \$permissions\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$conf(windows)\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::set\ permissions\ 0666\n\ \ \ \ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::set\ permissions\ \$info(DefaultFilePermission)\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\n\tif\ \{!\$size\}\ \{\n\t\ \ \ \ if\ \{\[catch\ \{\ open\ \$dest\ w\ \$permissions\ \}\ err\]\}\ \{\n\t\treturn\ -code\ error\ \$err\n\t\ \ \ \ \}\n\t\ \ \ \ close\ \$err\n\t\}\ else\ \{\n\t\ \ \ \ ::InstallJammer::unpack\ \$src\ \$dest\ \$permissions\n\t\}\n\n\ \ \ \ \ \ \ \ ##\ Set\ the\ modified\ time\ to\ the\ one\ we\ have\ stored.\n\ \ \ \ \ \ \ \ if\ \{\$mtime\}\ \{\ file\ mtime\ \$dest\ \$mtime\ \}\n\n\ \ \ \ \ \ \ \ if\ \{\$logFile\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ ::InstallJammer::LogFile\ \$dest\n\ \ \ \ \ \ \ \ \ \ \ \ ::InstallJammer::SetVersionInfo\ \$dest\ \$version\n\ \ \ \ \ \ \ \ \}\n\n\treturn\ \$dest\n\ \ \ \ \}\n\n\ \ \ \ method\ group\ \{\}\ \{\n\ \ \ \ \ \ \ \ return\ \[lindex\ \[parent\ recursive\]\ 1\]\n\ \ \ \ \}\n\n\ \ \ \ method\ set\ \{\ args\ \}\ \{\n\ \ \ \ \ \ \ \ return\ \[eval\ ::InstallJammer::SetObjectProperties\ \$id\ \$args\]\n\ \ \ \ \}\n\n\ \ \ \ method\ get\ \{\ property\ \{varName\ \"\"\}\ \}\ \{\n\ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$varName\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ upvar\ 1\ \$varName\ var\n\ \ \ \ \ \ \ \ \ \ \ \ return\ \[::InstallJammer::GetObjectProperty\ \$id\ \$property\ var\]\n\ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ return\ \[::InstallJammer::GetObjectProperty\ \$id\ \$property\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ method\ isfile\ \{\}\ \{\n\ \ \ \ \ \ \ \ return\ \[is\ file\ link\]\n\ \ \ \ \}\n\n\ \ \ \ method\ object\ \{\}\ \{\n\ \ \ \ \ \ \ \ return\ ::FileObject\n\ \ \ \ \}\n\n\ \ \ \ method\ name\ \ \ \ \ \ \ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ name\ \ \ \ \ \ \ \ \$args\ \}\n\ \ \ \ method\ size\ \ \ \ \ \ \ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ size\ \ \ \ \ \ \ \ \$args\ \}\n\ \ \ \ method\ mtime\ \ \ \ \ \ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ mtime\ \ \ \ \ \ \ \$args\ \}\n\ \ \ \ method\ version\ \ \ \ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ version\ \ \ \ \ \$args\ \}\n\ \ \ \ method\ directory\ \ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ directory\ \ \ \$args\ \}\n\ \ \ \ method\ filemethod\ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ filemethod\ \ \$args\ \}\n\ \ \ \ method\ attributes\ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ attributes\ \ \$args\ \}\n\ \ \ \ method\ permissions\ \ \{\ args\ \}\ \{\ eval\ cfgvar\ permissions\ \$args\ \}\n\n\ \ \ \ public\ variable\ name\ \ \ \ \ \ \ \ \ \ \"\"\n\ \ \ \ public\ variable\ size\ \ \ \ \ \ \ \ \ \ 0\n\ \ \ \ public\ variable\ mtime\ \ \ \ \ \ \ \ \ 0\n\ \ \ \ public\ variable\ version\ \ \ \ \ \ \ \"\"\n\ \ \ \ public\ variable\ directory\ \ \ \ \ \"\"\n\ \ \ \ public\ variable\ filemethod\ \ \ \ \"\"\n\ \ \ \ public\ variable\ attributes\ \ \ \ \"\"\n\ \ \ \ public\ variable\ permissions\ \ \ \"\"\n\n\ \ \ \ private\ variable\ exists\n\n\}\ \;\ ##\ itcl::class\ File\n\n::itcl::class\ InstallComponent\ \{\n\ \ \ \ inherit\ TreeObject\n\n\ \ \ \ constructor\ \{\ args\ \}\ \{\ \n\ \ \ \ \ \ \ \ eval\ configure\ \$args\n\ \ \ \ \}\ \{\n\ \ \ \ \ \ \ \ ::set\ name\ \[string\ tolower\ \$id\]\n\ \ \ \ \ \ \ \ ::set\ type\ installcomponent\n\n\ \ \ \ \ \ \ \ eval\ configure\ \$args\n\n\ \ \ \ \ \ \ \ ##\ If\ this\ is\ a\ temporary\ object,\ we\ don't\ want\ to\ append\n\ \ \ \ \ \ \ \ ##\ it\ to\ the\ lists\ or\ do\ any\ further\ setup.\n\ \ \ \ \ \ \ \ if\ \{\$temp\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$parent\]\}\ \{\ \$parent\ children\ remove\ \$id\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ return\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ if\ \{\[info\ exists\ ::InstallJammer::Properties(\$id,Alias)\]\n\ \ \ \ \ \ \ \ \ \ \ \ &&\ \[string\ length\ \$::InstallJammer::Properties(\$id,Alias)\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \$this\ set\ Alias\ \$::InstallJammer::Properties(\$id,Alias)\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ ##\ Do\ some\ special\ setup\ if\ this\ is\ a\ pane,\ and\ we're\n\ \ \ \ \ \ \ \ ##\ building\ it\ from\ within\ an\ installer.\n\ \ \ \ \ \ \ \ if\ \{!\[info\ exists\ ::InstallJammer\]\ &&\ \[ispane\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ ::set\ install\ \$parent\n\ \ \ \ \ \ \ \ \ \ \ \ ::set\ wizard\ \ \$::info(Wizard)\n\n\ \ \ \ \ \ \ \ \ \ \ \ ::set\ node\ \$parent\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[\$parent\ is\ installtype\]\}\ \{\ ::set\ node\ root\ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ equal\ \$install\ \"Common\"\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::InstallJammer::CreateWindow\ \$wizard\ \$id\n\ \ \ \ \ \ \ \ \ \ \ \ \}\ elseif\ \{\[string\ equal\ \$install\ \$::info(InstallMode)\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::set\ create\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \[list\ ::InstallJammer::CreateWindow\ \$wizard\ \$id\]\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ get\ WizardOptions\ stepopts\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ eval\ \[list\ \$wizard\ insert\ step\ end\ \$node\ \$id\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -createcommand\ \$create\]\ \$stepopts\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[is\ window\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \$wizard\ itemconfigure\ \$id\ -appendorder\ 0\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ destructor\ \{\n\ \ \ \ \ \ \ \ if\ \{!\$temp\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ array\ unset\ ::InstallJammer::Properties\ \$id,*\n\n\ \ \ \ \ \ \ \ \ \ \ \ foreach\ condition\ \$conditions\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ catch\ \{\ \$condition\ destroy\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ method\ set\ \{\ args\ \}\ \{\n\ \ \ \ \ \ \ \ return\ \[eval\ ::InstallJammer::SetObjectProperties\ \$id\ \$args\]\n\ \ \ \ \}\n\n\ \ \ \ method\ get\ \{\ property\ \{varName\ \"\"\}\ \}\ \{\n\ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$varName\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ upvar\ 1\ \$varName\ var\n\ \ \ \ \ \ \ \ \ \ \ \ return\ \[::InstallJammer::GetObjectProperty\ \$id\ \$property\ var\]\n\ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ return\ \[::InstallJammer::GetObjectProperty\ \$id\ \$property\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ method\ properties\ \{\ arrayName\ args\ \}\ \{\n\ \ \ \ \ \ \ \ upvar\ 1\ \$arrayName\ array\n\ \ \ \ \ \ \ \ return\ \[eval\ ::InstallJammer::ObjectProperties\ \$id\ array\ \$args\]\n\ \ \ \ \}\n\n\ \ \ \ method\ ispane\ \{\}\ \{\n\ \ \ \ \ \ \ \ return\ \[expr\ \{\[is\ \"pane\"\]\ ||\ \[is\ \"window\"\]\}\]\n\ \ \ \ \}\n\n\ \ \ \ method\ object\ \{\}\ \{\n\ \ \ \ \ \ \ \ if\ \{\[ispane\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ variable\ ::InstallJammer::panes\n\ \ \ \ \ \ \ \ \ \ \ \ return\ \$panes(\$component)\n\ \ \ \ \ \ \ \ \}\ elseif\ \{\[is\ action\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ variable\ ::InstallJammer::actions\n\ \ \ \ \ \ \ \ \ \ \ \ return\ \$actions(\$component)\n\ \ \ \ \ \ \ \ \}\ elseif\ \{\[is\ actiongroup\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ return\ ActionGroupObject\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ method\ initialize\ \{\}\ \{\n\ \ \ \ \ \ \ \ \[object\]\ initialize\ \$id\n\ \ \ \ \}\n\n\ \ \ \ method\ widget\ \{\ command\ widget\ args\ \}\ \{\n\ \ \ \ \ \ \ \ switch\ --\ \$command\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \"get\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[info\ exists\ widgetData(\$widget,widget)\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ \$widgetData(\$widget,widget)\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \"set\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[lsearch\ -exact\ \$widgets\ \$widget\]\ <\ 0\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ lappend\ widgets\ \$widget\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ foreach\ \[list\ opt\ val\]\ \$args\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::set\ widgetData(\$widget,\[string\ range\ \$opt\ 1\ end\])\ \$val\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \"type\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[info\ exists\ widgetData(\$widget,type)\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ \$widgetData(\$widget,type)\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ text\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ method\ widgets\ \{\}\ \{\n\ \ \ \ \ \ \ \ return\ \$widgets\n\ \ \ \ \}\n\n\ \ \ \ method\ conditions\ \{\ args\ \}\ \{\n\ \ \ \ \ \ \ \ if\ \{\[lempty\ \$args\]\}\ \{\ return\ \$conditions\ \}\n\n\ \ \ \ \ \ \ \ lassign\ \$args\ command\ obj\n\ \ \ \ \ \ \ \ switch\ --\ \$command\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \"add\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ conditions\ insert\ end\ \$obj\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \"index\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ \[lsearch\ -exact\ \$conditions\ \$obj\]\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \"insert\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ lassign\ \$args\ command\ index\ obj\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[lsearch\ -exact\ \$conditions\ \$obj\]\ >\ -1\}\ \{\ return\ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$index\ eq\ \"end\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ lappend\ conditions\ \$obj\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::set\ conditions\ \[linsert\ \$conditions\ \$index\ \$obj\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \"remove\"\ -\ \"delete\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::set\ conditions\ \[lremove\ \$conditions\ \$obj\]\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \"reorder\"\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::set\ conditions\ \$obj\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ return\n\ \ \ \ \}\n\n\ \ \ \ method\ checkConditions\ \{\ \{when\ \"\"\}\ \}\ \{\n\ \ \ \ \ \ \ \ if\ \{\[ispane\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ global\ info\n\ \ \ \ \ \ \ \ \ \ \ \ ::set\ info(CurrentPane)\ \$id\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ if\ \{\[llength\ \$conditions\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ ::set\ conditionlist\ \$conditions\n\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$when\ ne\ \"\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::set\ conditionlist\ \[list\]\n\ \ \ \ \ \ \ \ \ \ \ \ foreach\ cid\ \$conditions\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$when\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::set\ check\ \[\$cid\ get\ CheckCondition\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ equal\ -nocase\ \$when\ \$check\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ lappend\ conditionlist\ \$cid\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[llength\ \$conditionlist\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::set\ msg\ \"Checking\ conditions\ for\ \$id\ -\ \$title\"\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$when\ ne\ \"\"\}\ \{\ append\ msg\ \"\ -\ \$when\"\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ debug\ \$msg\ \$id\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ foreach\ cid\ \$conditionlist\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ debug\ \"Checking\ condition\ \$cid\ -\ \[\$cid\ title\]\"\ \$cid\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{!\[\$cid\ check\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ debug\ \"Condition\ failed\"\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ 0\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ debug\ \"Condition\ passed\"\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ return\ 1\n\ \ \ \ \}\n\n\ \ \ \ method\ setup\ \ \ \ \ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ setup\ \ \ \ \ \ \ \$args\ \}\n\ \ \ \ method\ title\ \ \ \ \ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ title\ \ \ \ \ \ \ \$args\ \}\n\ \ \ \ method\ window\ \ \ \ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ window\ \ \ \ \ \ \$args\ \}\n\ \ \ \ method\ created\ \ \ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ created\ \ \ \ \ \$args\ \}\n\ \ \ \ method\ command\ \ \ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ command\ \ \ \ \ \$args\ \}\n\ \ \ \ method\ component\ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ component\ \ \ \$args\ \}\n\ \ \ \ method\ arguments\ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ arguments\ \ \ \$args\ \}\n\ \ \ \ method\ description\ \{\ args\ \}\ \{\ eval\ cfgvar\ description\ \$args\ \}\n\n\ \ \ \ public\ variable\ setup\ \ \ \ \ \ \ \"\"\n\ \ \ \ public\ variable\ title\ \ \ \ \ \ \ \"\"\n\ \ \ \ public\ variable\ window\ \ \ \ \ \ \"\"\n\ \ \ \ public\ variable\ created\ \ \ \ \ 0\n\ \ \ \ \n\ \ \ \ public\ variable\ command\ \ \ \ \ \"\"\n\ \ \ \ public\ variable\ component\ \ \ \"\"\n\ \ \ \ public\ variable\ arguments\ \ \ \"\"\n\ \ \ \ public\ variable\ conditions\ \ \[list\]\n\ \ \ \ public\ variable\ description\ \"\"\n\n\ \ \ \ private\ variable\ widgets\ \ \ \ \[list\]\n\ \ \ \ private\ variable\ widgetData\n\}\ \;\ ##\ ::itcl::class\ InstallComponent\n\n::itcl::class\ FileGroup\ \{\n\ \ \ \ inherit\ InstallComponent\n\n\ \ \ \ constructor\ \{\ args\ \}\ \{\n\ \ \ \ \ \ \ \ eval\ configure\ \$args\n\ \ \ \ \}\ \{\n\ \ \ \ \ \ \ \ eval\ configure\ \$args\n\ \ \ \ \ \ \ \ ::set\ type\ \ filegroup\n\ \ \ \ \ \ \ \ ::set\ setup\ Install\n\ \ \ \ \}\n\n\ \ \ \ method\ install\ \{\}\ \{\n\ \ \ \ \ \ \ \ global\ conf\n\n\ \ \ \ \ \ \ \ ::set\ dir\ \[directory\]\n\n\ \ \ \ \ \ \ \ ::InstallJammer::CreateDir\ \$dir\n\n\ \ \ \ \ \ \ \ if\ \{\$conf(windows)\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ ::InstallJammer::SetPermissions\ \$dir\ \[get\ Attributes\]\n\ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ ::InstallJammer::SetPermissions\ \$dir\ \[get\ Permissions\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ method\ directory\ \{\}\ \{\n\ \ \ \ \ \ \ \ return\ \[::InstallJammer::SubstText\ \[get\ Destination\]\]\n\ \ \ \ \}\n\n\ \ \ \ method\ version\ \{\}\ \{\n\ \ \ \ \ \ \ \ return\ \[get\ Version\]\n\ \ \ \ \}\n\n\ \ \ \ method\ filemethod\ \{\}\ \{\n\ \ \ \ \ \ \ \ return\ \[get\ FileUpdateMethod\]\n\ \ \ \ \}\n\n\ \ \ \ method\ object\ \{\}\ \{\n\ \ \ \ \ \ \ \ return\ ::FileGroupObject\n\ \ \ \ \}\n\}\ \;\ ##\ ::itcl::class\ FileGroup\n\n::itcl::class\ Component\ \{\n\ \ \ \ inherit\ InstallComponent\n\n\ \ \ \ constructor\ \{\ args\ \}\ \{\n\ \ \ \ \ \ \ \ eval\ configure\ \$args\n\ \ \ \ \}\ \{\n\ \ \ \ \ \ \ \ eval\ configure\ \$args\n\ \ \ \ \ \ \ \ ::set\ type\ \ component\n\ \ \ \ \ \ \ \ ::set\ setup\ Install\n\ \ \ \ \}\n\n\ \ \ \ method\ object\ \{\}\ \{\n\ \ \ \ \ \ \ \ return\ ::ComponentObject\n\ \ \ \ \}\n\}\ \;\ ##\ ::itcl::class\ Component\n\n::itcl::class\ SetupType\ \{\n\ \ \ \ inherit\ InstallComponent\n\n\ \ \ \ constructor\ \{\ args\ \}\ \{\n\ \ \ \ \ \ \ \ eval\ configure\ \$args\n\ \ \ \ \}\ \{\n\ \ \ \ \ \ \ \ eval\ configure\ \$args\n\ \ \ \ \ \ \ \ ::set\ type\ \ setuptype\n\ \ \ \ \ \ \ \ ::set\ setup\ Install\n\ \ \ \ \}\n\n\ \ \ \ method\ object\ \{\}\ \{\n\ \ \ \ \ \ \ \ return\ ::SetupTypeObject\n\ \ \ \ \}\n\}\ \;\ ##\ ::itcl::class\ SetupType\n\n::itcl::class\ Condition\ \{\n\ \ \ \ inherit\ Object\n\n\ \ \ \ constructor\ \{\ args\ \}\ \{\n\ \ \ \ \ \ \ \ ::set\ id\ \[namespace\ tail\ \$this\]\n\ \ \ \ \ \ \ \ eval\ configure\ \$args\n\n\ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$parent\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \$parent\ conditions\ add\ \$id\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ destructor\ \{\n\ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$parent\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \$parent\ conditions\ remove\ \$id\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ method\ serialize\ \{\}\ \{\n\ \ \ \ \ \ \ \ ::set\ return\ \[list\]\n\ \ \ \ \ \ \ \ foreach\ list\ \[configure\]\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ ::set\ opt\ \[lindex\ \$list\ 0\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$opt\ eq\ \"-id\"\}\ \{\ continue\ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ ::set\ def\ \[lindex\ \$list\ end-1\]\n\ \ \ \ \ \ \ \ \ \ \ \ ::set\ val\ \[lindex\ \$list\ end\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$def\ ==\ \$val\}\ \{\ continue\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ return\ \$opt\ \$val\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ return\ \$return\n\ \ \ \ \}\n\n\ \ \ \ method\ set\ \{\ args\ \}\ \{\n\ \ \ \ \ \ \ \ return\ \[eval\ ::InstallJammer::SetObjectProperties\ \$id\ \$args\]\n\ \ \ \ \}\n\n\ \ \ \ method\ get\ \{\ property\ \{varName\ \"\"\}\ \}\ \{\n\ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$varName\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ upvar\ 1\ \$varName\ var\n\ \ \ \ \ \ \ \ \ \ \ \ return\ \[::InstallJammer::GetObjectProperty\ \$id\ \$property\ var\]\n\ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ return\ \[::InstallJammer::GetObjectProperty\ \$id\ \$property\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\n\ \ \ \ method\ properties\ \{\ arrayName\ args\ \}\ \{\n\ \ \ \ \ \ \ \ upvar\ 1\ \$arrayName\ array\n\ \ \ \ \ \ \ \ return\ \[eval\ ::InstallJammer::ObjectProperties\ \$id\ array\ \$args\]\n\ \ \ \ \}\n\n\ \ \ \ method\ object\ \{\}\ \{\n\ \ \ \ \ \ \ \ return\ \$::InstallJammer::conditions(\$component)\n\ \ \ \ \}\n\n\ \ \ \ method\ check\ \{\}\ \{\n\ \ \ \ \ \ \ \ ::set\ res\ \[string\ is\ true\ \[::InstallJammer::conditions::\$component\ \$id\]\]\n\ \ \ \ \ \ \ \ if\ \{!\$res\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ ::set\ msg\ \[::InstallJammer::SubstText\ \[get\ FailureMessage\]\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$msg\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::InstallJammer::MessageBox\ -icon\ error\ -message\ \$msg\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ return\ \$res\n\ \ \ \ \}\n\n\ \ \ \ method\ id\ \ \ \ \ \ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ id\ \ \ \ \ \ \ \ \$args\ \}\n\ \ \ \ method\ title\ \ \ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ title\ \ \ \ \ \$args\ \}\n\ \ \ \ method\ active\ \ \ \ \{\ args\ \}\ \{\ eval\ cfgvar\ active\ \ \ \ \$args\ \}\n\ \ \ \ method\ component\ \{\ args\ \}\ \{\ eval\ cfgvar\ component\ \$args\ \}\n\n\ \ \ \ public\ variable\ id\ \ \ \ \ \ \ \ \"\"\n\ \ \ \ public\ variable\ title\ \ \ \ \ \"\"\n\ \ \ \ public\ variable\ active\ \ \ \ 1\n\ \ \ \ public\ variable\ parent\ \ \ \ \"\"\n\ \ \ \ public\ variable\ component\ \"\"\n\}\ \;\ ##\ ::itcl::class\ Condition\n\n##\ \$Id\$\n##\n##\ Copyright\ (C)\ 2002\ \ Damon\ Courtney\n##\ \n##\ This\ program\ is\ free\ software\;\ you\ can\ redistribute\ it\ and/or\n##\ modify\ it\ under\ the\ terms\ of\ the\ GNU\ General\ Public\ License\n##\ as\ published\ by\ the\ Free\ Software\ Foundation\;\ either\ version\ 2\n##\ of\ the\ License,\ or\ (at\ your\ option)\ any\ later\ version.\n##\ \n##\ This\ program\ is\ distributed\ in\ the\ hope\ that\ it\ will\ be\ useful,\n##\ but\ WITHOUT\ ANY\ WARRANTY\;\ without\ even\ the\ implied\ warranty\ of\n##\ MERCHANTABILITY\ or\ FITNESS\ FOR\ A\ PARTICULAR\ PURPOSE.\ \ See\ the\n##\ GNU\ General\ Public\ License\ for\ more\ details.\n##\ \n##\ You\ should\ have\ received\ a\ copy\ of\ the\ GNU\ General\ Public\ License\n##\ along\ with\ this\ program\;\ if\ not,\ write\ to\ the\n##\ \ \ \ \ Free\ Software\ Foundation,\ Inc.\n##\ \ \ \ \ 51\ Franklin\ Street,\ Fifth\ Floor\n##\ \ \ \ \ Boston,\ MA\ \ 02110-1301,\ USA.\n##\n\nnamespace\ eval\ ::installkit\ \{\}\n\n##\ Create\ a\ generic\ InstallKit\ from\ the\ current\ running\ process.\nproc\ ::installkit::base\ \{\ \{installkit\ \"\"\}\ \}\ \{\n\ \ \ \ global\ info\n\ \ \ \ if\ \{!\[string\ length\ \$installkit\]\}\ \{\n\ \ \ \ \ \ \ \ set\ installkit\ \[::InstallJammer::TmpDir\ installkit\$info(Ext)\]\n\ \ \ \ \}\n\n\ \ \ \ if\ \{!\[file\ exists\ \$installkit\]\}\ \{\n\ \ \ \ \ \ \ \ set\ installkit\ \[::InstallJammer::Wrap\ -o\ \$installkit\]\n\ \ \ \ \}\n\n\ \ \ \ return\ \[::InstallJammer::Normalize\ \$installkit\]\n\}\n\nproc\ ::installkit::WrapProgress\ \{total\ size\ bytes\}\ \{\n\ \ \ \ global\ conf\n\ \ \ \ iincr\ conf(wrapTotal)\ \$bytes.0\n\ \ \ \ iincr\ conf(wrapSoFar)\ \$bytes.0\n\ \ \ \ if\ \{\$total\ >\ 0\}\ \{\n\tset\ x\ \[expr\ round(\ (\$conf(wrapTotal)\ *\ 100.0)\ /\ \$total\ )\]\n\tputs\ stdout\ \":PERCENT\ \$x\"\n\tflush\ stdout\n\ \ \ \ \}\n\ \ \ \ if\ \{\$size\ >\ 0\}\ \{\n\tset\ x\ \[expr\ round(\ (\$conf(wrapSoFar)\ *\ 100.0)\ /\ \$size\ )\]\n\tputs\ stdout\ \":FILEPERCENT\ \$x\"\n\tflush\ stdout\n\ \ \ \ \}\n\}\n\nproc\ ::installkit::WrapUnpack\ \{ifp\ ofp\ total\ size\ bytes\ \{error\ \"\"\}\}\ \{\n\ \ \ \ global\ conf\n\ \ \ \ WrapProgress\ \$total\ \$size\ \$bytes\n\ \ \ \ if\ \{\[string\ length\ \$error\]\ >\ 0\ ||\ \[eof\ \$ifp\]\}\ \{\n\tclose\ \$ifp\n\tclose\ \$ofp\n\tset\ ::conf(wrapDone)\ 1\n\ \ \ \ \}\ else\ \{\n\t::fcopy\ \$ifp\ \$ofp\ -size\ 50000\ \\\n\t\ \ \ \ -command\ \[list\ ::installkit::WrapUnpack\ \$ifp\ \$ofp\ \$total\ \$size\]\n\ \ \ \ \}\n\}\n\nproc\ ::installkit::Mount\ \{\ zipFile\ mountPoint\ \}\ \{\n\ \ \ \ zvfs::mount\ \$zipFile\ \$mountPoint\n\}\n\nproc\ ::installkit::Unmount\ \{\ mountPoint\ \}\ \{\n\ \ \ \ zvfs::unmount\ \$mountPoint\n\} uninstall.tcl {## $Id$
  13473. ##
  13474. ## Copyright (C) 2002  Damon Courtney
  13475. ## 
  13476. ## This program is free software; you can redistribute it and/or
  13477. ## modify it under the terms of the GNU General Public License
  13478. ## as published by the Free Software Foundation; either version 2
  13479. ## of the License, or (at your option) any later version.
  13480. ## 
  13481. ## This program is distributed in the hope that it will be useful,
  13482. ## but WITHOUT ANY WARRANTY; without even the implied warranty of
  13483. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13484. ## GNU General Public License for more details.
  13485. ## 
  13486. ## You should have received a copy of the GNU General Public License
  13487. ## along with this program; if not, write to the
  13488. ##     Free Software Foundation, Inc.
  13489. ##     51 Franklin Street, Fifth Floor
  13490. ##     Boston, MA  02110-1301, USA.
  13491. ##
  13492.  
  13493. if {[info exists ::InstallJammer]} { return }
  13494.  
  13495. catch { wm withdraw . }
  13496.  
  13497. namespace eval ::InstallJammer {}
  13498.  
  13499. trace add variable ::info write ::InstallJammer::AdjustBooleanVars
  13500.  
  13501. proc ::InstallJammer::AdjustBooleanVars { name1 name2 op } {
  13502.     ## If a user is typing into an entry that has a -textvariable
  13503.     ## in the info array, we don't want to adjust what the user is typing.
  13504.     if {![catch { lindex [info level -1] 0 } cmd]} {
  13505.         if {$cmd eq "tk::EntryInsert" || $cmd eq "tile::entry::Insert"} {
  13506.             return
  13507.         }
  13508.     }
  13509.  
  13510.     if {[string length $name2]} {
  13511.         upvar #0 ${name1}($name2) var
  13512.     } else {
  13513.         upvar #0 $name1 var
  13514.     }
  13515.  
  13516.     if {[info exists var]} {
  13517.         if {[string is true -strict $var]} {
  13518.             set var 1
  13519.         } elseif {[string is false -strict $var]} {
  13520.             set var 0
  13521.         }
  13522.     }
  13523. }
  13524.  
  13525. set PaneList {Uninstall UninstallComplete UninstallDetails}
  13526. array set ::InstallJammer::Properties {
  13527. 1016F936-2BE9-4ECB-8539-82A68DBBAA74,Active
  13528. Yes
  13529.  
  13530. 1016F936-2BE9-4ECB-8539-82A68DBBAA74,Alias
  13531. {Uninstall Actions}
  13532.  
  13533. 1016F936-2BE9-4ECB-8539-82A68DBBAA74,Comment
  13534. {}
  13535.  
  13536. 1016F936-2BE9-4ECB-8539-82A68DBBAA74,Conditions
  13537. {}
  13538.  
  13539. 1016F936-2BE9-4ECB-8539-82A68DBBAA74,ID
  13540. {}
  13541.  
  13542. 213B7E89-C364-4995-859C-ABA65D4C3EDE,Action
  13543. {Uninstall Actions}
  13544.  
  13545. 213B7E89-C364-4995-859C-ABA65D4C3EDE,Active
  13546. Yes
  13547.  
  13548. 213B7E89-C364-4995-859C-ABA65D4C3EDE,Alias
  13549. {}
  13550.  
  13551. 213B7E89-C364-4995-859C-ABA65D4C3EDE,Comment
  13552. {}
  13553.  
  13554. 213B7E89-C364-4995-859C-ABA65D4C3EDE,Component
  13555. {}
  13556.  
  13557. 213B7E89-C364-4995-859C-ABA65D4C3EDE,Conditions
  13558. {}
  13559.  
  13560. 213B7E89-C364-4995-859C-ABA65D4C3EDE,EvaluateConditions
  13561. Yes
  13562.  
  13563. 213B7E89-C364-4995-859C-ABA65D4C3EDE,ExecuteAction
  13564. {After Pane is Displayed}
  13565.  
  13566. 213B7E89-C364-4995-859C-ABA65D4C3EDE,ID
  13567. {}
  13568.  
  13569. 213B7E89-C364-4995-859C-ABA65D4C3EDE,IgnoreErrors
  13570. No
  13571.  
  13572. 22B753EA-DE2A-4B20-A945-224738E90986,Active
  13573. Yes
  13574.  
  13575. 22B753EA-DE2A-4B20-A945-224738E90986,Alias
  13576. {Finish Actions}
  13577.  
  13578. 22B753EA-DE2A-4B20-A945-224738E90986,Comment
  13579. {}
  13580.  
  13581. 22B753EA-DE2A-4B20-A945-224738E90986,Conditions
  13582. {}
  13583.  
  13584. 22B753EA-DE2A-4B20-A945-224738E90986,ID
  13585. {}
  13586.  
  13587. 35AA10E9-28BC-4695-BC2F-68DA00EE1E4D,Active
  13588. Yes
  13589.  
  13590. 35AA10E9-28BC-4695-BC2F-68DA00EE1E4D,Alias
  13591. {}
  13592.  
  13593. 35AA10E9-28BC-4695-BC2F-68DA00EE1E4D,Comment
  13594. {}
  13595.  
  13596. 35AA10E9-28BC-4695-BC2F-68DA00EE1E4D,Component
  13597. {}
  13598.  
  13599. 35AA10E9-28BC-4695-BC2F-68DA00EE1E4D,Conditions
  13600. {0 conditions}
  13601.  
  13602. 35AA10E9-28BC-4695-BC2F-68DA00EE1E4D,ExecuteAction
  13603. {After Pane is Displayed}
  13604.  
  13605. 35AA10E9-28BC-4695-BC2F-68DA00EE1E4D,Files
  13606. <%InstallDir%>/Settings.ini
  13607.  
  13608. 35AA10E9-28BC-4695-BC2F-68DA00EE1E4D,ID
  13609. {}
  13610.  
  13611. 35AA10E9-28BC-4695-BC2F-68DA00EE1E4D,IgnoreErrors
  13612. Yes
  13613.  
  13614. 39A03798-2744-48BB-8077-84B333E50E14,Active
  13615. Yes
  13616.  
  13617. 39A03798-2744-48BB-8077-84B333E50E14,Alias
  13618. {}
  13619.  
  13620. 39A03798-2744-48BB-8077-84B333E50E14,BackButton,subst
  13621. 1
  13622.  
  13623. 39A03798-2744-48BB-8077-84B333E50E14,Buttons
  13624. Next/Cancel
  13625.  
  13626. 39A03798-2744-48BB-8077-84B333E50E14,CancelButton,subst
  13627. 1
  13628.  
  13629. 39A03798-2744-48BB-8077-84B333E50E14,Caption,subst
  13630. 1
  13631.  
  13632. 39A03798-2744-48BB-8077-84B333E50E14,Comment
  13633. {}
  13634.  
  13635. 39A03798-2744-48BB-8077-84B333E50E14,Component
  13636. {}
  13637.  
  13638. 39A03798-2744-48BB-8077-84B333E50E14,Conditions
  13639. {1 condition}
  13640.  
  13641. 39A03798-2744-48BB-8077-84B333E50E14,ID
  13642. {}
  13643.  
  13644. 39A03798-2744-48BB-8077-84B333E50E14,Icon
  13645. <%Icon%>
  13646.  
  13647. 39A03798-2744-48BB-8077-84B333E50E14,Message,subst
  13648. 1
  13649.  
  13650. 39A03798-2744-48BB-8077-84B333E50E14,NextButton,subst
  13651. 1
  13652.  
  13653. 39A03798-2744-48BB-8077-84B333E50E14,Subtitle,subst
  13654. 1
  13655.  
  13656. 39A03798-2744-48BB-8077-84B333E50E14,Text,subst
  13657. 1
  13658.  
  13659. 39A03798-2744-48BB-8077-84B333E50E14,Title,subst
  13660. 1
  13661.  
  13662. 47F70A4D-19E3-4751-B84C-E544AB8FD345,Active
  13663. Yes
  13664.  
  13665. 47F70A4D-19E3-4751-B84C-E544AB8FD345,Alias
  13666. {Startup Actions}
  13667.  
  13668. 47F70A4D-19E3-4751-B84C-E544AB8FD345,Comment
  13669. {}
  13670.  
  13671. 47F70A4D-19E3-4751-B84C-E544AB8FD345,Conditions
  13672. {0 conditions}
  13673.  
  13674. 47F70A4D-19E3-4751-B84C-E544AB8FD345,ID
  13675. {}
  13676.  
  13677. 579EFC8C-CC0C-4446-84A0-B218E254A6E7,Active
  13678. Yes
  13679.  
  13680. 579EFC8C-CC0C-4446-84A0-B218E254A6E7,Alias
  13681. {}
  13682.  
  13683. 579EFC8C-CC0C-4446-84A0-B218E254A6E7,Comment
  13684. {}
  13685.  
  13686. 579EFC8C-CC0C-4446-84A0-B218E254A6E7,Component
  13687. {}
  13688.  
  13689. 579EFC8C-CC0C-4446-84A0-B218E254A6E7,Conditions
  13690. {}
  13691.  
  13692. 579EFC8C-CC0C-4446-84A0-B218E254A6E7,ExecuteAction
  13693. {After Pane is Displayed}
  13694.  
  13695. 579EFC8C-CC0C-4446-84A0-B218E254A6E7,ID
  13696. {}
  13697.  
  13698. 579EFC8C-CC0C-4446-84A0-B218E254A6E7,IgnoreErrors
  13699. No
  13700.  
  13701. 616C0583-E61A-4F7C-B865-9089F3B745FA,Action
  13702. {Uninstall Actions}
  13703.  
  13704. 616C0583-E61A-4F7C-B865-9089F3B745FA,Active
  13705. Yes
  13706.  
  13707. 616C0583-E61A-4F7C-B865-9089F3B745FA,Alias
  13708. {}
  13709.  
  13710. 616C0583-E61A-4F7C-B865-9089F3B745FA,Comment
  13711. {}
  13712.  
  13713. 616C0583-E61A-4F7C-B865-9089F3B745FA,Component
  13714. {}
  13715.  
  13716. 616C0583-E61A-4F7C-B865-9089F3B745FA,Conditions
  13717. {}
  13718.  
  13719. 616C0583-E61A-4F7C-B865-9089F3B745FA,EvaluateConditions
  13720. Yes
  13721.  
  13722. 616C0583-E61A-4F7C-B865-9089F3B745FA,ExecuteAction
  13723. {After Pane is Displayed}
  13724.  
  13725. 616C0583-E61A-4F7C-B865-9089F3B745FA,ID
  13726. {}
  13727.  
  13728. 616C0583-E61A-4F7C-B865-9089F3B745FA,IgnoreErrors
  13729. No
  13730.  
  13731. 93DC7CF7-979D-45D2-AD0F-CAFAEA76373B,Active
  13732. Yes
  13733.  
  13734. 93DC7CF7-979D-45D2-AD0F-CAFAEA76373B,Alias
  13735. {}
  13736.  
  13737. 93DC7CF7-979D-45D2-AD0F-CAFAEA76373B,CheckCondition
  13738. {Before Pane is Displayed}
  13739.  
  13740. 93DC7CF7-979D-45D2-AD0F-CAFAEA76373B,Comment
  13741. {}
  13742.  
  13743. 93DC7CF7-979D-45D2-AD0F-CAFAEA76373B,Component
  13744. {}
  13745.  
  13746. 93DC7CF7-979D-45D2-AD0F-CAFAEA76373B,FailureMessage
  13747. {}
  13748.  
  13749. 93DC7CF7-979D-45D2-AD0F-CAFAEA76373B,ID
  13750. {}
  13751.  
  13752. 93DC7CF7-979D-45D2-AD0F-CAFAEA76373B,Operator
  13753. true
  13754.  
  13755. 93DC7CF7-979D-45D2-AD0F-CAFAEA76373B,String
  13756. <%ErrorsOccurred%>
  13757.  
  13758. 9A3D786A-9CE4-4F36-8EAD-C0A12029BF1A,Active
  13759. Yes
  13760.  
  13761. 9A3D786A-9CE4-4F36-8EAD-C0A12029BF1A,Alias
  13762. {Cancel Actions}
  13763.  
  13764. 9A3D786A-9CE4-4F36-8EAD-C0A12029BF1A,Comment
  13765. {}
  13766.  
  13767. 9A3D786A-9CE4-4F36-8EAD-C0A12029BF1A,Conditions
  13768. {}
  13769.  
  13770. 9A3D786A-9CE4-4F36-8EAD-C0A12029BF1A,ID
  13771. {}
  13772.  
  13773. 9C5D86BD-8E00-4D68-B230-100344377DB1,Active
  13774. Yes
  13775.  
  13776. 9C5D86BD-8E00-4D68-B230-100344377DB1,Alias
  13777. {}
  13778.  
  13779. 9C5D86BD-8E00-4D68-B230-100344377DB1,CheckCondition
  13780. {Before Pane is Displayed}
  13781.  
  13782. 9C5D86BD-8E00-4D68-B230-100344377DB1,Comment
  13783. {}
  13784.  
  13785. 9C5D86BD-8E00-4D68-B230-100344377DB1,Component
  13786. {}
  13787.  
  13788. 9C5D86BD-8E00-4D68-B230-100344377DB1,FailureMessage
  13789. {}
  13790.  
  13791. 9C5D86BD-8E00-4D68-B230-100344377DB1,ID
  13792. {}
  13793.  
  13794. 9C5D86BD-8E00-4D68-B230-100344377DB1,Operator
  13795. true
  13796.  
  13797. 9C5D86BD-8E00-4D68-B230-100344377DB1,String
  13798. <%ErrorsOccurred%>
  13799.  
  13800. A2364EBD-0BAE-4C4B-BF65-D486384DFFE2,Active
  13801. Yes
  13802.  
  13803. A2364EBD-0BAE-4C4B-BF65-D486384DFFE2,Alias
  13804. {}
  13805.  
  13806. A2364EBD-0BAE-4C4B-BF65-D486384DFFE2,Comment
  13807. {}
  13808.  
  13809. A2364EBD-0BAE-4C4B-BF65-D486384DFFE2,Component
  13810. {}
  13811.  
  13812. A2364EBD-0BAE-4C4B-BF65-D486384DFFE2,Conditions
  13813. {}
  13814.  
  13815. A2364EBD-0BAE-4C4B-BF65-D486384DFFE2,ExecuteAction
  13816. {After Pane is Displayed}
  13817.  
  13818. A2364EBD-0BAE-4C4B-BF65-D486384DFFE2,ID
  13819. {}
  13820.  
  13821. A2364EBD-0BAE-4C4B-BF65-D486384DFFE2,IgnoreErrors
  13822. No
  13823.  
  13824. DB6D2B8B-FC79-4E20-B2AD-566D8767FCBC,Active
  13825. Yes
  13826.  
  13827. DB6D2B8B-FC79-4E20-B2AD-566D8767FCBC,Alias
  13828. {}
  13829.  
  13830. DB6D2B8B-FC79-4E20-B2AD-566D8767FCBC,CheckCondition
  13831. {Before Pane is Displayed}
  13832.  
  13833. DB6D2B8B-FC79-4E20-B2AD-566D8767FCBC,Comment
  13834. {}
  13835.  
  13836. DB6D2B8B-FC79-4E20-B2AD-566D8767FCBC,Component
  13837. {}
  13838.  
  13839. DB6D2B8B-FC79-4E20-B2AD-566D8767FCBC,DefaultButton
  13840. Yes
  13841.  
  13842. DB6D2B8B-FC79-4E20-B2AD-566D8767FCBC,FailureMessage
  13843. {}
  13844.  
  13845. DB6D2B8B-FC79-4E20-B2AD-566D8767FCBC,ID
  13846. {}
  13847.  
  13848. DB6D2B8B-FC79-4E20-B2AD-566D8767FCBC,Icon
  13849. info
  13850.  
  13851. DB6D2B8B-FC79-4E20-B2AD-566D8767FCBC,Message,subst
  13852. 1
  13853.  
  13854. DB6D2B8B-FC79-4E20-B2AD-566D8767FCBC,ResultVirtualText
  13855. Answer
  13856.  
  13857. DB6D2B8B-FC79-4E20-B2AD-566D8767FCBC,Title,subst
  13858. 1
  13859.  
  13860. DB6D2B8B-FC79-4E20-B2AD-566D8767FCBC,TrueValue
  13861. Yes
  13862.  
  13863. E0E9AB16-3718-4359-99DE-7A7B80960AFF,Active
  13864. Yes
  13865.  
  13866. E0E9AB16-3718-4359-99DE-7A7B80960AFF,Alias
  13867. {}
  13868.  
  13869. E0E9AB16-3718-4359-99DE-7A7B80960AFF,Comment
  13870. {}
  13871.  
  13872. E0E9AB16-3718-4359-99DE-7A7B80960AFF,Component
  13873. {}
  13874.  
  13875. E0E9AB16-3718-4359-99DE-7A7B80960AFF,Conditions
  13876. {}
  13877.  
  13878. E0E9AB16-3718-4359-99DE-7A7B80960AFF,ExecuteAction
  13879. {After Pane is Displayed}
  13880.  
  13881. E0E9AB16-3718-4359-99DE-7A7B80960AFF,ID
  13882. {}
  13883.  
  13884. E0E9AB16-3718-4359-99DE-7A7B80960AFF,IgnoreErrors
  13885. No
  13886.  
  13887. E0FCA78E-F97E-4D8A-B800-6A1E33E5D8DB,Active
  13888. Yes
  13889.  
  13890. E0FCA78E-F97E-4D8A-B800-6A1E33E5D8DB,Alias
  13891. {}
  13892.  
  13893. E0FCA78E-F97E-4D8A-B800-6A1E33E5D8DB,Comment
  13894. {}
  13895.  
  13896. E0FCA78E-F97E-4D8A-B800-6A1E33E5D8DB,Component
  13897. {}
  13898.  
  13899. E0FCA78E-F97E-4D8A-B800-6A1E33E5D8DB,Conditions
  13900. {}
  13901.  
  13902. E0FCA78E-F97E-4D8A-B800-6A1E33E5D8DB,ExecuteAction
  13903. {After Pane is Displayed}
  13904.  
  13905. E0FCA78E-F97E-4D8A-B800-6A1E33E5D8DB,ExitType
  13906. Finish
  13907.  
  13908. E0FCA78E-F97E-4D8A-B800-6A1E33E5D8DB,ID
  13909. {}
  13910.  
  13911. E0FCA78E-F97E-4D8A-B800-6A1E33E5D8DB,IgnoreErrors
  13912. No
  13913.  
  13914. E407FB36-48CE-4081-9051-6BAA771E761A,Active
  13915. Yes
  13916.  
  13917. E407FB36-48CE-4081-9051-6BAA771E761A,Alias
  13918. {}
  13919.  
  13920. E407FB36-48CE-4081-9051-6BAA771E761A,BackButton,subst
  13921. 1
  13922.  
  13923. E407FB36-48CE-4081-9051-6BAA771E761A,Buttons
  13924. Next/Cancel
  13925.  
  13926. E407FB36-48CE-4081-9051-6BAA771E761A,CancelButton,subst
  13927. 1
  13928.  
  13929. E407FB36-48CE-4081-9051-6BAA771E761A,Caption,subst
  13930. 1
  13931.  
  13932. E407FB36-48CE-4081-9051-6BAA771E761A,Comment
  13933. {}
  13934.  
  13935. E407FB36-48CE-4081-9051-6BAA771E761A,Component
  13936. {}
  13937.  
  13938. E407FB36-48CE-4081-9051-6BAA771E761A,Conditions
  13939. {0 conditions}
  13940.  
  13941. E407FB36-48CE-4081-9051-6BAA771E761A,ID
  13942. {}
  13943.  
  13944. E407FB36-48CE-4081-9051-6BAA771E761A,Image
  13945. <%Image%>
  13946.  
  13947. E407FB36-48CE-4081-9051-6BAA771E761A,Message,subst
  13948. 1
  13949.  
  13950. E407FB36-48CE-4081-9051-6BAA771E761A,NextButton,subst
  13951. 1
  13952.  
  13953. E407FB36-48CE-4081-9051-6BAA771E761A,WizardOptions
  13954. {-bg white -separator 0}
  13955.  
  13956. F799E315-34DC-4C43-9820-835EFE017509,Active
  13957. Yes
  13958.  
  13959. F799E315-34DC-4C43-9820-835EFE017509,Alias
  13960. {}
  13961.  
  13962. F799E315-34DC-4C43-9820-835EFE017509,Comment
  13963. {}
  13964.  
  13965. F799E315-34DC-4C43-9820-835EFE017509,Component
  13966. {}
  13967.  
  13968. F799E315-34DC-4C43-9820-835EFE017509,Conditions
  13969. {}
  13970.  
  13971. F799E315-34DC-4C43-9820-835EFE017509,ExecuteAction
  13972. {After Pane is Displayed}
  13973.  
  13974. F799E315-34DC-4C43-9820-835EFE017509,ID
  13975. {}
  13976.  
  13977. F799E315-34DC-4C43-9820-835EFE017509,IgnoreErrors
  13978. No
  13979.  
  13980. F799E315-34DC-4C43-9820-835EFE017509,State
  13981. disabled
  13982.  
  13983. F799E315-34DC-4C43-9820-835EFE017509,Text
  13984. {}
  13985.  
  13986. F799E315-34DC-4C43-9820-835EFE017509,Widget
  13987. {NextButton; CancelButton}
  13988.  
  13989. F8912289-F9F6-4C2E-8058-C38BD7F3E27B,Active
  13990. Yes
  13991.  
  13992. F8912289-F9F6-4C2E-8058-C38BD7F3E27B,Alias
  13993. {}
  13994.  
  13995. F8912289-F9F6-4C2E-8058-C38BD7F3E27B,BackButton,subst
  13996. 1
  13997.  
  13998. F8912289-F9F6-4C2E-8058-C38BD7F3E27B,Buttons
  13999. Next/Cancel
  14000.  
  14001. F8912289-F9F6-4C2E-8058-C38BD7F3E27B,CancelButton,subst
  14002. 1
  14003.  
  14004. F8912289-F9F6-4C2E-8058-C38BD7F3E27B,Caption,subst
  14005. 1
  14006.  
  14007. F8912289-F9F6-4C2E-8058-C38BD7F3E27B,Comment
  14008. {}
  14009.  
  14010. F8912289-F9F6-4C2E-8058-C38BD7F3E27B,Component
  14011. {}
  14012.  
  14013. F8912289-F9F6-4C2E-8058-C38BD7F3E27B,Conditions
  14014. {0 conditions}
  14015.  
  14016. F8912289-F9F6-4C2E-8058-C38BD7F3E27B,FileValue,subst
  14017. 1
  14018.  
  14019. F8912289-F9F6-4C2E-8058-C38BD7F3E27B,ID
  14020. {}
  14021.  
  14022. F8912289-F9F6-4C2E-8058-C38BD7F3E27B,Icon
  14023. <%Icon%>
  14024.  
  14025. F8912289-F9F6-4C2E-8058-C38BD7F3E27B,Message,subst
  14026. 1
  14027.  
  14028. F8912289-F9F6-4C2E-8058-C38BD7F3E27B,NextButton,subst
  14029. 1
  14030.  
  14031. F8912289-F9F6-4C2E-8058-C38BD7F3E27B,ProgressValue,subst
  14032. 1
  14033.  
  14034. F8912289-F9F6-4C2E-8058-C38BD7F3E27B,Subtitle,subst
  14035. 1
  14036.  
  14037. F8912289-F9F6-4C2E-8058-C38BD7F3E27B,Title,subst
  14038. 1
  14039.  
  14040. Linux-x86,Active
  14041. No
  14042.  
  14043. Linux-x86,BuildType
  14044. dynamic
  14045.  
  14046. Linux-x86,DefaultDirectoryPermission
  14047. 00755
  14048.  
  14049. Linux-x86,DefaultFilePermission
  14050. 00755
  14051.  
  14052. Linux-x86,Executable
  14053. <%AppName%>-<%Version%>-<%Platform%>-Install<%Ext%>
  14054.  
  14055. Linux-x86,InstallDir
  14056. <%Home%>/<%ShortAppName%>
  14057.  
  14058. Linux-x86,InstallType
  14059. Typical
  14060.  
  14061. Linux-x86,ProgramExecutable
  14062. <%InstallDir%>/CompleteCalc
  14063.  
  14064. Linux-x86,ProgramFolderAllUsers
  14065. No
  14066.  
  14067. Linux-x86,ProgramFolderName
  14068. <%AppName%>
  14069.  
  14070. Linux-x86,ProgramLicense
  14071. <%InstallDir%>/LICENSE.txt
  14072.  
  14073. Linux-x86,ProgramName
  14074. {}
  14075.  
  14076. Linux-x86,ProgramReadme
  14077. <%InstallDir%>/README.txt
  14078.  
  14079. Linux-x86,RequireRoot
  14080. No
  14081.  
  14082. Linux-x86,RootInstallDir
  14083. /usr/local/<%ShortAppName%>
  14084.  
  14085. Windows,Active
  14086. Yes
  14087.  
  14088. Windows,BuildType
  14089. {}
  14090.  
  14091. Windows,Executable
  14092. <%AppName%>-<%Version%>-Setup<%Ext%>
  14093.  
  14094. Windows,IncludeTWAPI
  14095. No
  14096.  
  14097. Windows,InstallDir
  14098. <%PROGRAM_FILES%>/<%AppName%>
  14099.  
  14100. Windows,InstallType
  14101. Typical
  14102.  
  14103. Windows,ProgramExecutable
  14104. <%InstallDir%>/CompleteCalc.exe
  14105.  
  14106. Windows,ProgramFolderAllUsers
  14107. No
  14108.  
  14109. Windows,ProgramFolderName
  14110. <%AppName%>
  14111.  
  14112. Windows,ProgramLicense
  14113. <%InstallDir%>/LICENSE.txt
  14114.  
  14115. Windows,ProgramName
  14116. {}
  14117.  
  14118. Windows,ProgramReadme
  14119. <%InstallDir%>/README.txt
  14120.  
  14121. Windows,WindowsIcon
  14122. {Setup Blue Screen.ico}
  14123.  
  14124. }
  14125. namespace eval ::InstallJammer::actions {}
  14126. proc ::InstallJammer::actions::DeleteFile {obj} {
  14127.     $obj properties props
  14128.  
  14129.     foreach file [::InstallJammer::GetFilesForPattern $props(Files)] {
  14130.         file delete -force $file
  14131.     }
  14132. }
  14133.  
  14134. proc ::InstallJammer::actions::ExecuteAction {obj} {
  14135.     set id [$obj id]
  14136.  
  14137.     if {[$obj get Action action] && [string length $action]} {
  14138.         $obj get EvaluateConditions eval
  14139.         return [::InstallJammer::ExecuteActions $action  -parent $id -conditions $eval]
  14140.     }
  14141. }
  14142.  
  14143. proc ::InstallJammer::actions::Exit {obj} {
  14144.     global info
  14145.  
  14146.     if {[$obj get ExitType] eq "Cancel"} {
  14147.         set info(InstallCancelled) 1
  14148.     }
  14149.         
  14150.     ## Walk through a list of possible exit routines and
  14151.     ## choose the best one we have.
  14152.     foreach command [list ::Exit ::InstallJammer::exit ::exit] {
  14153.         if {[::InstallJammer::CommandExists $command]} {
  14154.             $command
  14155.         }
  14156.     }
  14157. }
  14158.  
  14159. proc ::InstallJammer::actions::ModifyWidget {obj} {
  14160.     global info
  14161.  
  14162.     set parent [$obj parent]
  14163.  
  14164.     $obj properties props
  14165.  
  14166.     if {![string length $props(Widget)]} { return }
  14167.  
  14168.     set args [list]
  14169.     if {[string length $props(Text)]}  { lappend args -text $props(Text) }
  14170.     if {[string length $props(State)]} { lappend args -state $props(State) }
  14171.  
  14172.     if {![llength $args]} { return }
  14173.  
  14174.     foreach widget [split $props(Widget) \;] {
  14175.         set widget [join [string trim $widget] ""]
  14176.         switch -- $widget {
  14177.             "BackButton" - "NextButton" - "CancelButton" {
  14178.                 set widget [string tolower [string map {Button ""} $widget]]
  14179.                 eval [list $info(Wizard) itemconfigure $widget] $args
  14180.             }
  14181.  
  14182.             default {
  14183.                 set widget [$parent widget get $widget]
  14184.                 eval [list $widget configure] $args
  14185.             }
  14186.         }
  14187.     }
  14188.  
  14189.     update idletasks
  14190. }
  14191.  
  14192. proc ::InstallJammer::actions::MoveForward {obj} {
  14193.     global info
  14194.  
  14195.     set next [$info(Wizard) step next]
  14196.  
  14197.     ## If this is the last step, call the action to exit the install.
  14198.     if {![string length $next]} {
  14199.         ::InstallJammer::actions::Exit $obj
  14200.     } else {
  14201.         after 0 [list $info(Wizard) next 1]
  14202.     }
  14203. }
  14204.  
  14205. proc ::InstallJammer::actions::UninstallLeftoverFiles {obj} {
  14206.     ::InstallJammer::actions::UninstallSelectedFiles $obj 1
  14207. }
  14208.  
  14209. proc ::InstallJammer::actions::UninstallSelectedFiles {obj {force 0}} {
  14210.     global conf
  14211.     global info
  14212.  
  14213.     set id     [$obj id]
  14214.     set parent [$obj parent]
  14215.  
  14216.     set info(Errors)                ""
  14217.     set info(FileBeingUninstalled)  ""
  14218.     set info(GroupBeingUninstalled) ""
  14219.  
  14220.     ::InstallJammer::UpdateWidgets -update 1
  14221.  
  14222.     if {!$force} {
  14223.     if {[catch { open $info(InstallLog) } fp]} { return }
  14224.     while {[gets $fp line] != -1} {
  14225.         lappend array([lindex $line 0]) [lrange $line 1 end]
  14226.     }
  14227.     close $fp
  14228.     } else {
  14229.     upvar #0 ::leftovers array
  14230.     }
  14231.  
  14232.     set fileLen 0
  14233.     if {[info exists array(:FILE)]} {
  14234.     set fileLen [llength $array(:FILE)]
  14235.     }
  14236.  
  14237.     set dirLen 0
  14238.     if {[info exists array(:DIR)]} {
  14239.     set dirLen [llength $array(:DIR)]
  14240.     }
  14241.  
  14242.     set regLen 0
  14243.     if {[info exists array(:REGISTRY)]} {
  14244.     set regLen [llength $array(:REGISTRY)]
  14245.     }
  14246.  
  14247.     set conf(total) [expr $fileLen + $dirLen + $regLen]
  14248.  
  14249.     set info(Status) "<%FileBeingUninstalledText%>"
  14250.  
  14251.     set info(GroupBeingUninstalled) "files"
  14252.     ::InstallJammer::UpdateWidgets -update 1
  14253.  
  14254.     for {set i [expr $fileLen -1]} {$i >= 0} {incr i -1} {
  14255.     set list [lindex $array(:FILE) $i]
  14256.     set file [lindex $list 0]
  14257.         set tail [file tail $file]
  14258.  
  14259.     set info(FileBeingUninstalled) $tail
  14260.         ::InstallJammer::UpdateUninstallProgress
  14261.  
  14262.     if {[catch {::InstallJammer::UninstallFile $file} error]} {
  14263.         lappend ::leftovers(:FILE) $list
  14264.         append info(Errors) "$error\n"
  14265.     }
  14266.     }
  14267.  
  14268.     set info(GroupBeingUninstalled) "directories"
  14269.     ::InstallJammer::UpdateWidgets -update 1
  14270.  
  14271.     set p $::tcl_platform(platform)
  14272.     set installdir [::InstallJammer::Normalize $info(InstallDir)]
  14273.     for {set i [expr $dirLen -1]} {$i >= 0} {incr i -1} {
  14274.     set list [lindex $array(:DIR) $i]
  14275.     lassign $list dir forcedir
  14276.     if {$force} { set forcedir -force }
  14277.  
  14278.     set info(FileBeingUninstalled) [file tail $dir]
  14279.         ::InstallJammer::UpdateUninstallProgress
  14280.  
  14281.     if {!$force && ![::InstallJammer::DirIsEmpty $dir]} {
  14282.             ## Make a special case for directories named after
  14283.             ## the Company.  This is a common thing on Windows,
  14284.             ## and we don't want to blow away the whole company
  14285.             ## directory even if our program was the one who
  14286.             ## installed it.
  14287.             if {[lindex [file split $dir] end] ne $info(Company)} {
  14288.                 lappend ::leftovers(:DIR) $list
  14289.                 append info(Errors) "[::InstallJammer::Normalize $dir $p] "
  14290.                 append info(Errors) "is not empty\n"
  14291.             }
  14292.  
  14293.             continue
  14294.     }
  14295.  
  14296.     if {[catch {::InstallJammer::UninstallDirectory $dir $forcedir} err]} {
  14297.         append info(Errors) "$err\n"
  14298.     }
  14299.     }
  14300.  
  14301.     if {$conf(windows)} {
  14302.         set info(GroupBeingUninstalled)     "registry entries"
  14303.         ::InstallJammer::UpdateWidgets -update 1
  14304.  
  14305.         set command ::InstallJammer::UninstallRegistryKey
  14306.         for {set i [expr $regLen -1]} {$i >= 0} {incr i -1} {
  14307.             set list [lindex $array(:REGISTRY) $i]
  14308.             lassign $list key value
  14309.             ::InstallJammer::UpdateUninstallProgress
  14310.  
  14311.             if {[catch {eval $command $list} error]} {
  14312.                 lappend ::leftovers(:REGISTRY) $list
  14313.                 append info(Errors) "Could not remove $list: $error\n"
  14314.             }
  14315.         }
  14316.     }
  14317.  
  14318.     ## Cleanup the install registry.
  14319.     set infodir [::InstallJammer::InstallInfoDir]
  14320.     if {[file exists $infodir]} {
  14321.         catch { file delete -force $infodir }
  14322.     }
  14323.  
  14324.     set info(ErrorsOccurred) [expr {[string length $info(Errors)] > 0}]
  14325.  
  14326.     return 1
  14327. }
  14328.  
  14329.  
  14330. proc ::InstallJammer::conditions::AskYesOrNo {obj} {
  14331.     $obj properties props
  14332.  
  14333.     set id [$obj id]
  14334.  
  14335.     set title   [::InstallJammer::GetText $id Title]
  14336.     set message [::InstallJammer::GetText $id Message]
  14337.  
  14338.     set args [list -type yesno -title $title -message $message]
  14339.     lappend args -icon $props(Icon)
  14340.     lappend args -default [string tolower $props(DefaultButton)]
  14341.     lappend args -parent [::InstallJammer::TransientParent]
  14342.  
  14343.     set result [eval ::InstallJammer::MessageBox $args]
  14344.  
  14345.     if {[string length $props(ResultVirtualText)]} {
  14346.         global info
  14347.         set info($props(ResultVirtualText)) $result
  14348.     }
  14349.  
  14350.     return [string equal -nocase $result $props(TrueValue)]
  14351. }
  14352.  
  14353. proc ::InstallJammer::conditions::StringIsCondition {obj} {
  14354.     $obj properties props
  14355.  
  14356.     debug "Checking to see if $props(String) is $props(Operator)"
  14357.  
  14358.     set string [::InstallJammer::SubstText $props(String)]
  14359.     return [string is $props(Operator) $string]
  14360. }
  14361.  
  14362.  
  14363. proc CreateWindow.Uninstall {wizard id} {
  14364.     CreateWindow.CustomBlankPane2 $wizard $id
  14365.  
  14366.     set base [$id widget get ClientArea]
  14367.  
  14368.     grid rowconfigure    $base 0 -weight 1
  14369.     grid columnconfigure $base 0 -weight 1
  14370.  
  14371.     set frame [frame $base.frame]
  14372.     grid $frame -row 0 -column 0 -sticky new
  14373.  
  14374.     grid rowconfigure    $frame 1 -weight 1
  14375.     grid columnconfigure $frame 0 -weight 1
  14376.  
  14377.     label $frame.file -anchor w
  14378.     grid  $frame.file -row 0 -column 0 -sticky new
  14379.     $id widget set FileValue -widget $frame.file
  14380.  
  14381.     ttk::progressbar $frame.progress
  14382.     grid $frame.progress -row 1 -column 0 -sticky ew
  14383.     $id widget set ProgressValue -widget $frame.progress -type progress
  14384. }
  14385.  
  14386. proc CreateWindow.UninstallDetails {wizard id} {
  14387.     CreateWindow.CustomTextPane1 $wizard $id
  14388. }
  14389.  
  14390. proc CreateWindow.UninstallComplete {wizard id} {
  14391.     CreateWindow.CustomBlankPane1 $wizard $id
  14392. }
  14393.  
  14394. proc CreateWindow.CustomBlankPane2 {wizard id} {
  14395.     set base  [$wizard widget get $id]
  14396.     set frame $base.titleframe
  14397.  
  14398.     grid rowconfigure    $base 3 -weight 1
  14399.     grid columnconfigure $base 0 -weight 1
  14400.  
  14401.     frame $frame -bd 0 -relief flat -background white
  14402.     grid  $frame -row 0 -column 0 -sticky nsew
  14403.  
  14404.     grid rowconfigure    $frame 1 -weight 1
  14405.     grid columnconfigure $frame 0 -weight 1
  14406.  
  14407.     Label $frame.title -background white -anchor nw -justify left -autowrap 1  -font TkCaptionFont -textvariable [$wizard variable $id -text1]
  14408.     grid $frame.title -row 0 -column 0 -sticky new -padx 5 -pady 5
  14409.     $id widget set Title -widget $frame.title
  14410.  
  14411.     Label $frame.subtitle -background white -anchor nw -autowrap 1  -justify left -textvariable [$wizard variable $id -text2]
  14412.     grid $frame.subtitle -row 1 -column 0 -sticky new -padx [list 20 5]
  14413.     $id widget set Subtitle -widget $frame.subtitle
  14414.  
  14415.     label $frame.icon -borderwidth 0 -background white -anchor c
  14416.     grid  $frame.icon -row 0 -column 1 -rowspan 2
  14417.     $id widget set Icon -widget $frame.icon -type image
  14418.  
  14419.     Separator $base.separator -relief groove -orient horizontal
  14420.     grid $base.separator -row 1 -column 0 -sticky ew 
  14421.  
  14422.     Label $base.caption -anchor nw -justify left -autowrap 1  -textvariable [$wizard variable $id -text3]
  14423.     grid $base.caption -row 2 -sticky nsew -padx 8 -pady [list 8 4]
  14424.     $id widget set Caption -widget $base.caption
  14425.  
  14426.     frame $base.clientarea
  14427.     grid  $base.clientarea -row 3 -sticky nsew -padx 8 -pady 4
  14428.     $id widget set ClientArea -widget $base.clientarea -type frame
  14429.  
  14430.     Label $base.message -anchor nw -justify left -autowrap 1  -textvariable [$wizard variable $id -text4]
  14431.     grid $base.message -row 4 -sticky nsew -padx 8 -pady [list 4 8]
  14432.     $id widget set Message -widget $base.message
  14433. }
  14434.  
  14435. proc CreateWindow.CustomTextPane1 {wizard id} {
  14436.     CreateWindow.CustomBlankPane2 $wizard $id
  14437.  
  14438.     set base [$id widget get ClientArea]
  14439.  
  14440.     grid rowconfigure    $base 0 -weight 1
  14441.     grid columnconfigure $base 0 -weight 1
  14442.  
  14443.     frame $base.frame
  14444.     grid  $base.frame -row 0 -column 0 -sticky news
  14445.     
  14446.     grid rowconfigure    $base.frame 0 -weight 1
  14447.     grid columnconfigure $base.frame 0 -weight 1
  14448.  
  14449.     if {![$id get TextFont font]} { set font TkTextFont }
  14450.  
  14451.     text $base.frame.text  -bg white -font $font -wrap word -highlightthickness 0  -yscrollcommand "$base.frame.vs set"  -xscrollcommand "$base.frame.hs set"
  14452.     grid $base.frame.text -row 0 -column 0 -sticky news
  14453.     $id widget set Text -widget $base.frame.text
  14454.  
  14455.     ttk::scrollbar $base.frame.vs -command "$base.frame.text yview"
  14456.     grid $base.frame.vs -row 0 -column 1 -sticky ns
  14457.  
  14458.     ttk::scrollbar $base.frame.hs -command "$base.frame.text xview"  -orient horizontal
  14459.     grid $base.frame.hs -row 1 -column 0 -sticky ew
  14460. }
  14461.  
  14462. proc CreateWindow.CustomBlankPane1 {wizard id} {
  14463.     set base [$wizard widget get $id]
  14464.  
  14465.     grid rowconfigure    $base 1 -weight 1
  14466.     grid columnconfigure $base 1 -weight 1
  14467.  
  14468.     label $base.image -borderwidth 0
  14469.     grid  $base.image -row 0 -column 0 -rowspan 2 -sticky nw
  14470.     $id widget set Image -type image -widget $base.image
  14471.  
  14472.     Label $base.title -height 3 -bg white -font TkCaptionFont  -autowrap 1 -anchor nw -justify left
  14473.     grid $base.title -row 0 -column 1 -sticky ew -padx 20 -pady [list 20 10]
  14474.     $id widget set Caption -type text -widget $base.title
  14475.  
  14476.     Label $base.message -bg white -autowrap 1 -anchor nw -justify left
  14477.     grid  $base.message -row 1 -column 1 -sticky news -padx 20
  14478.     $id widget set Message -type text -widget $base.message
  14479.  
  14480.     Separator $base.sep -orient horizontal
  14481.     grid $base.sep -row 2 -column 0 -columnspan 2 -sticky ew
  14482. }
  14483.  
  14484.  
  14485. proc ThemeInit {} {
  14486. global info
  14487.  
  14488. Wizard $info(Wizard) -width 500 -height 365  -raisecommand  [list RaiseStep %W %S]  -separatortext "Check n Do"  -title [::InstallJammer::SubstText "Uninstall <%AppName%>"]
  14489.  
  14490. bind $info(Wizard) <<WizardFinish>> [list ::InstallJammer::exit 1]
  14491.  
  14492. if {$::tcl_platform(platform) eq "unix"} {
  14493. $info(Wizard) configure -bg [style configure . -background]
  14494. }
  14495. }
  14496.  
  14497.  
  14498. if {[info exists ::InstallJammer]} { return }
  14499.  
  14500. proc ::InstallJammer::UpdateUninstallProgress {} {
  14501. global conf
  14502. global info
  14503.  
  14504. incr0 conf(num)
  14505. set pct [expr ($conf(num) * 100) / $conf(total)]
  14506. set info(UninstallPercentComplete) $pct
  14507.  
  14508. ::InstallJammer::UpdateWidgets -update 1
  14509. }
  14510.  
  14511. proc ::InstallJammer::exit { {prompt 0} } {
  14512. global conf
  14513. global info
  14514.  
  14515. if {$info(WizardStarted) && !$info(InstallCancelled)} {
  14516. ::InstallJammer::ExecuteActions "Finish Actions"
  14517. } else {
  14518. ::InstallJammer::ExecuteActions "Cancel Actions"
  14519. }
  14520.  
  14521. if {$conf(windows)} { ::InstallJammer::WriteDoneFile }
  14522.  
  14523. if {$conf(debugging) && [info exists ::debugfp]} { close $::debugfp }
  14524.  
  14525. ::exit
  14526. }
  14527.  
  14528. proc ::InstallJammer::UninstallMain {} {
  14529. global conf
  14530. global info
  14531.  
  14532. if {$::tcl_platform(platform) eq "unix"} {
  14533. if {$info(RequireRoot) && !$info(UserIsRoot)} {
  14534. ::InstallJammer::Message -title "Root Required" -message  "You must be root to run uninstall this application."
  14535. exit 1
  14536. }
  14537. }
  14538.  
  14539. if {$info(SilentMode)} {
  14540. if {$conf(windows)} {
  14541. after 1000
  14542. }
  14543.  
  14544. ::InstallJammer::ExecuteActions "Startup Actions"
  14545. ::InstallJammer::ExecuteActions Silent
  14546. } else {
  14547. BWidget::use ttk 1 -force
  14548.  
  14549. ::InstallJammer::ExecuteActions "Startup Actions"
  14550.  
  14551. set info(WizardStarted) 1
  14552. ::InstallJammer::CenterWindow $info(Wizard)
  14553. ::InstallJammer::Wizard next
  14554. }
  14555. }
  14556.  
  14557. proc ::InstallJammer::InitUninstall {} {
  14558. global conf
  14559. global info
  14560. global argv
  14561.  
  14562. ::InstallJammer::CommonInit
  14563.  
  14564. if {$conf(windows)} {
  14565. package require Wintcl
  14566.  
  14567. set uninstall $conf(exe)
  14568. set test [file join [file dirname $uninstall] .uninstall]
  14569. if {![file exists $test]} {
  14570. set new [::InstallJammer::TmpDir [file tail $uninstall]]
  14571. file copy $uninstall $new
  14572. close [open [::InstallJammer::TmpDir .uninstall] w]
  14573. eval exec [list $new] $argv &
  14574. ::exit
  14575. }
  14576.  
  14577. set info(Temp) [file dirname $uninstall]
  14578. cd $info(Temp)
  14579. }
  14580.  
  14581. ::InstallJammer::ReadMessageCatalog messages
  14582.  
  14583. set conf(stop)  [::InstallJammer::TmpDir .stop]
  14584. set conf(pause) [::InstallJammer::TmpDir .pause]
  14585.  
  14586. array set info {
  14587. ErrorsOccurred            0
  14588. FileBeingUninstalled      ""
  14589. GroupBeingUninstalled     ""
  14590. UninstallPercentComplete  0
  14591.  
  14592. RunningUninstaller        1
  14593. }
  14594.  
  14595. set info(Status) "Preparing to uninstall..."
  14596.  
  14597. SafeArraySet info {
  14598. FileBeingUninstalledText  "Removing <%FileBeingUninstalled%>"
  14599. GroupBeingUninstalledText "Removing <%GroupBeingUninstalled%>"
  14600. }
  14601.  
  14602. lappend logs [file join $::installkit::root install.log]
  14603. lappend logs [::InstallJammer::InstallInfoDir install.log]
  14604. foreach log $logs {
  14605. if {[file exists $log]} {
  14606. set info(InstallLog) $log
  14607. break
  14608. }
  14609. }
  14610.  
  14611. foreach arg $argv {
  14612. switch -- $arg {
  14613. "-S" {
  14614. set info(SilentMode)  1
  14615. set info(InstallMode) "Silent"
  14616. }
  14617.  
  14618. "-Y" {
  14619. set info(DefaultMode) 1
  14620. set info(InstallMode) "Default"
  14621. }
  14622.  
  14623. default {
  14624. if {[file exists $arg]} {
  14625. set info(InstallLog) $arg
  14626. }
  14627.  
  14628. break
  14629. }
  14630. }
  14631. }
  14632.  
  14633. if {!$info(SilentMode)} { InitGui }
  14634. }
  14635.  
  14636. ::InstallJammer::InitUninstall
  14637.  
  14638.  
  14639.  
  14640.  
  14641. proc RaiseStep { wizard id } {
  14642. if {![string length [::InstallJammer::GetText $id Caption]]} {
  14643. grid remove [$id widget get Caption]
  14644. } else {
  14645. grid [$id widget get Caption]
  14646. }
  14647.  
  14648. if {![string length [::InstallJammer::GetText $id Message]]} {
  14649. grid remove [$id widget get Message]
  14650. } else {
  14651. grid [$id widget get Message]
  14652. }
  14653.  
  14654. if {[string length [$id widget get ClientArea]]} {
  14655. grid configure $wizard.buttons -pady {18 5}
  14656. } else {
  14657. grid configure $wizard.buttons -pady 5
  14658. }
  14659. }
  14660.  
  14661. InstallType ::Common
  14662. InstallType ::Standard
  14663. InstallComponent F8912289-F9F6-4C2E-8058-C38BD7F3E27B -setup Uninstall -title Uninstall -component Uninstall -type pane -active Yes -parent Standard
  14664. InstallComponent 35AA10E9-28BC-4695-BC2F-68DA00EE1E4D -setup Uninstall -title {Delete File} -component DeleteFile -type action -active Yes -parent F8912289-F9F6-4C2E-8058-C38BD7F3E27B
  14665. InstallComponent F799E315-34DC-4C43-9820-835EFE017509 -setup Uninstall -title {Modify Widget} -component ModifyWidget -type action -active Yes -parent F8912289-F9F6-4C2E-8058-C38BD7F3E27B
  14666. InstallComponent 616C0583-E61A-4F7C-B865-9089F3B745FA -setup Uninstall -title {Execute Action} -component ExecuteAction -type action -active Yes -parent F8912289-F9F6-4C2E-8058-C38BD7F3E27B
  14667. InstallComponent 579EFC8C-CC0C-4446-84A0-B218E254A6E7 -setup Uninstall -conditions {9C5D86BD-8E00-4D68-B230-100344377DB1 DB6D2B8B-FC79-4E20-B2AD-566D8767FCBC} -title {Uninstall Leftover Files} -component UninstallLeftoverFiles -command insert -type action -active Yes -parent F8912289-F9F6-4C2E-8058-C38BD7F3E27B
  14668. Condition 9C5D86BD-8E00-4D68-B230-100344377DB1 -active Yes -parent 579EFC8C-CC0C-4446-84A0-B218E254A6E7 -title {String Is Condition} -component StringIsCondition
  14669. Condition DB6D2B8B-FC79-4E20-B2AD-566D8767FCBC -active Yes -parent 579EFC8C-CC0C-4446-84A0-B218E254A6E7 -title {Ask Yes or No} -component AskYesOrNo
  14670. InstallComponent A2364EBD-0BAE-4C4B-BF65-D486384DFFE2 -setup Uninstall -title {Move Forward} -component MoveForward -type action -active Yes -parent F8912289-F9F6-4C2E-8058-C38BD7F3E27B
  14671. InstallComponent 39A03798-2744-48BB-8077-84B333E50E14 -setup Uninstall -conditions 93DC7CF7-979D-45D2-AD0F-CAFAEA76373B -title {Uninstall Details} -component UninstallDetails -command insert -type pane -active Yes -parent Standard
  14672. Condition 93DC7CF7-979D-45D2-AD0F-CAFAEA76373B -active Yes -parent 39A03798-2744-48BB-8077-84B333E50E14 -title {String Is Condition} -component StringIsCondition
  14673. InstallComponent E407FB36-48CE-4081-9051-6BAA771E761A -setup Uninstall -title {Uninstall Complete} -component UninstallComplete -type pane -active Yes -parent Standard
  14674. InstallType ::Default
  14675. InstallType ::Silent
  14676. InstallComponent 213B7E89-C364-4995-859C-ABA65D4C3EDE -setup Uninstall -title {Execute Action} -component ExecuteAction -type action -active Yes -parent Silent
  14677. InstallComponent E0FCA78E-F97E-4D8A-B800-6A1E33E5D8DB -setup Uninstall -title Exit -component Exit -type action -active Yes -parent Silent
  14678. InstallType ::ActionGroups
  14679. InstallComponent 47F70A4D-19E3-4751-B84C-E544AB8FD345 -setup Uninstall -title {Startup Actions} -type actiongroup -active Yes -parent ActionGroups
  14680. InstallComponent 1016F936-2BE9-4ECB-8539-82A68DBBAA74 -setup Uninstall -title {Uninstall Actions} -type actiongroup -active Yes -parent ActionGroups
  14681. InstallComponent E0E9AB16-3718-4359-99DE-7A7B80960AFF -setup Uninstall -title {Uninstall Selected Files} -component UninstallSelectedFiles -type action -active Yes -parent 1016F936-2BE9-4ECB-8539-82A68DBBAA74
  14682. InstallComponent 22B753EA-DE2A-4B20-A945-224738E90986 -setup Uninstall -title {Finish Actions} -type actiongroup -active Yes -parent ActionGroups
  14683. InstallComponent 9A3D786A-9CE4-4F36-8EAD-C0A12029BF1A -setup Uninstall -title {Cancel Actions} -type actiongroup -active Yes -parent ActionGroups
  14684.  
  14685.  
  14686. proc main {} {
  14687. ::InstallJammer::UninstallMain
  14688. }
  14689.  
  14690. if {![info exists ::InstallJammer]} { main }
  14691.  
  14692. } conditions.tcl {proc ::InstallJammer::conditions::FileExistsCondition {obj} {
  14693.     $obj properties props
  14694.  
  14695.     debug "Checking to see if $props(Filename) $props(Operator)"
  14696.     
  14697.     set file [::InstallJammer::SubstText $props(Filename)]
  14698.  
  14699.     if {$props(Operator) eq "exists"} {
  14700.         return [file exists $file]
  14701.     } else {
  14702.         return [expr {![file exists $file]}]
  14703.     }
  14704. }
  14705.  
  14706. proc ::InstallJammer::conditions::FilePermissionCondition {obj} {
  14707.     global conf
  14708.     global info
  14709.  
  14710.     $obj properties props
  14711.  
  14712.     if {$props(Permission) eq "can create"} {
  14713.         debug "Checking to see if we can create $props(Filename)"
  14714.     } else {
  14715.         debug "Checking to see if $props(Filename) $props(Permission)"
  14716.     }
  14717.  
  14718.     set file [::InstallJammer::SubstText $props(Filename)]
  14719.  
  14720.     switch -- $props(Permission) {
  14721.         "is readable" {
  14722.             return [file readable $file]
  14723.         }
  14724.  
  14725.         "is writable" {
  14726.             return [::InstallJammer::DirIsWritable $file]
  14727.         }
  14728.  
  14729.         "can create" {
  14730.             set info(Dir) $file
  14731.             if {[file exists $info(Dir)]} {
  14732.                 return [::InstallJammer::DirIsWritable $info(Dir)]
  14733.             }
  14734.  
  14735.             set info(Dir) $file
  14736.             while {![file exists $info(Dir)]} {
  14737.                 set info(Dir) [file dirname $info(Dir)]
  14738.                 if {[file exists $info(Dir)]} {
  14739.                     return [::InstallJammer::DirIsWritable $info(Dir)]
  14740.                 }
  14741.  
  14742.                 if {[llength [file split $info(Dir)]] <= 1} { return 0 }
  14743.             }
  14744.         }
  14745.     }
  14746. }
  14747.  
  14748. proc ::InstallJammer::conditions::PlatformCondition {obj} {
  14749.     global info
  14750.  
  14751.     $obj properties props
  14752.  
  14753.     debug "Checking to see if <%Platform%> $props(Operator) $props(Platform)"
  14754.  
  14755.     switch -- $props(Operator) {
  14756.         "is" {
  14757.             return [expr {$info(Platform) eq $props(Platform)}]
  14758.         }
  14759.  
  14760.         "is not" {
  14761.             return [expr {$info(Platform) ne $props(Platform)}]
  14762.         }
  14763.     }
  14764. }
  14765.  
  14766. proc ::InstallJammer::conditions::ScriptCondition {obj} {
  14767.     return [::InstallJammer::EvalCondition [$obj get Script]]
  14768. }
  14769.  
  14770. proc ::InstallJammer::conditions::StringIsCondition {obj} {
  14771.     $obj properties props
  14772.  
  14773.     debug "Checking to see if $props(String) is $props(Operator)"
  14774.  
  14775.     set string [::InstallJammer::SubstText $props(String)]
  14776.     return [string is $props(Operator) $string]
  14777. }
  14778.  
  14779. } unpack.tcl ##\ \$Id\$\n##\n##\ Copyright\ (C)\ 2002\ \ Damon\ Courtney\n##\ \n##\ This\ program\ is\ free\ software\;\ you\ can\ redistribute\ it\ and/or\n##\ modify\ it\ under\ the\ terms\ of\ the\ GNU\ General\ Public\ License\n##\ as\ published\ by\ the\ Free\ Software\ Foundation\;\ either\ version\ 2\n##\ of\ the\ License,\ or\ (at\ your\ option)\ any\ later\ version.\n##\ \n##\ This\ program\ is\ distributed\ in\ the\ hope\ that\ it\ will\ be\ useful,\n##\ but\ WITHOUT\ ANY\ WARRANTY\;\ without\ even\ the\ implied\ warranty\ of\n##\ MERCHANTABILITY\ or\ FITNESS\ FOR\ A\ PARTICULAR\ PURPOSE.\ \ See\ the\n##\ GNU\ General\ Public\ License\ for\ more\ details.\n##\ \n##\ You\ should\ have\ received\ a\ copy\ of\ the\ GNU\ General\ Public\ License\n##\ along\ with\ this\ program\;\ if\ not,\ write\ to\ the\n##\ \ \ \ \ Free\ Software\ Foundation,\ Inc.\n##\ \ \ \ \ 51\ Franklin\ Street,\ Fifth\ Floor\n##\ \ \ \ \ Boston,\ MA\ \ 02110-1301,\ USA.\n##\n\nif\ \{\[info\ exists\ ::InstallJammer\]\}\ \{\ return\ \}\n\nif\ \{\[info\ exists\ ::tcl_platform(threaded)\]\}\ \{\n\ \ \ \ proc\ output\ \{\ line\ \}\ \{\n\ \ \ \ \ \ \ \ thread::send\ \$::parentThread\ \[list\ ::InstallJammer::UnpackOutput\ \$line\]\n\ \ \ \ \}\n\}\ else\ \{\n\ \ \ \ proc\ output\ \{string\}\ \{\n\ \ \ \ \ \ \ \ global\ conf\n\n\ \ \ \ \ \ \ \ catch\ \{\ puts\ \$conf(runlogFp)\ \$string\ \}\n\ \ \ \ \ \ \ \ puts\ stdout\ \$string\n\n\ \ \ \ \ \ \ \ catch\ \{\ flush\ \$conf(runlogFp)\ \}\n\ \ \ \ \ \ \ \ flush\ stdout\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::InstallFiles\ \{\}\ \{\n\ \ \ \ global\ info\n\ \ \ \ global\ files\n\ \ \ \ global\ groups\n\n\ \ \ \ set\ info(unpackTotal)\ 0\n\n\ \ \ \ ::InstallJammer::CreateDir\ \$info(InstallDir)\n\n\ \ \ \ foreach\ group\ \$groups\ \{\n\ \ \ \ \ \ \ \ output\ \[list\ :GROUP\ \[\$group\ name\]\ \[\$group\ directory\]\]\n\n\ \ \ \ \ \ \ \ \$group\ install\n\n\ \ \ \ \ \ \ \ ##\ The\ group\ may\ not\ have\ any\ actual\ files.\n\ \ \ \ \ \ \ \ if\ \{!\[info\ exists\ files(\$group)\]\}\ \{\ continue\ \}\n\n\ \ \ \ \ \ \ \ foreach\ file\ \$files(\$group)\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ output\ \[list\ :FILE\ \[\$file\ destfile\]\ \[\$file\ version\]\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{!\[\$file\ install\]\}\ \{\ return\ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::IncrProgress\ \{bytes\}\ \{\n\ \ \ \ global\ info\n\n\ \ \ \ if\ \{\$info(TotalSize)\ ==\ 0\}\ \{\n\toutput\ \":PERCENT\ 100\"\n\treturn\n\ \ \ \ \}\n\ \ \ \ iincr\ info(unpackTotal)\ \$bytes.0\n\ \ \ \ iincr\ info(unpackSoFar)\ \$bytes.0\n\ \ \ \ if\ \{\$info(TotalSize)\ >\ 0\}\ \{\n\tset\ x\ \[expr\ round(\ (\$info(unpackTotal)\ *\ 100.0)\ /\ \$info(TotalSize)\ )\]\n\toutput\ \":PERCENT\ \$x\"\n\ \ \ \ \}\n\ \ \ \ if\ \{\$info(FileSize)\ >\ 0\}\ \{\n\tset\ x\ \[expr\ round(\ (\$info(unpackSoFar)\ *\ 100.0)\ /\ \$info(FileSize)\ )\]\n\toutput\ \":FILEPERCENT\ \$x\"\n\ \ \ \ \}\n\}\n\n#\ Unpack\ a\ file\ from\ the\ installer\ into\ a\ native\ location.\n#\n#\ path\ \ \ \ \ \ =\ path\ of\ packed\ file\ to\ unpack\n#\ destdir\ \ \ =\ optional\ destination\ directory\ for\ unpacked\ file.\n#\ chunkSize\ =\ The\ size\ of\ bites\ to\ read\ each\ time.\n#\n#\ Returns:\ on\ success,\ the\ name\ of\ the\ native\ file\n#\ \ \ \ \ \ \ \ \ \ on\ failure,\ an\ empty\ string\n#\nproc\ ::InstallJammer::unpack\ \{\ src\ dest\ \{permissions\ \"\"\}\ \}\ \{\n\ \ \ \ global\ conf\n\ \ \ \ global\ info\n\n\ \ \ \ if\ \{!\[PauseCheck\]\}\ \{\ return\ \}\n\n\ \ \ \ set\ chunkSize\ 50000\n\n\ \ \ \ if\ \{\$conf(rollback)\ &&\ \[file\ exists\ \$dest\]\}\ \{\n\ \ \ \ \ \ \ \ ::InstallJammer::SaveForRollback\ \$dest\n\ \ \ \ \}\n\n\ \ \ \ if\ \{!\[string\ length\ \$permissions\]\}\ \{\ set\ permissions\ 0666\ \}\n\n\ \ \ \ #\ Extract\ the\ file\ and\ copy\ it\ to\ its\ location.\n\ \ \ \ set\ fin\ \[open\ \$src\ r\]\n\ \ \ \ if\ \{\[catch\ \{open\ \$dest\ w\ \$permissions\}\ fout\]\}\ \{\n\tclose\ \$fin\n\treturn\ -code\ error\ \$fout\n\ \ \ \ \}\n\n\ \ \ \ fconfigure\ \$fin\ \ -translation\ binary\ -buffersize\ \$chunkSize\ -encoding\ binary\n\ \ \ \ fconfigure\ \$fout\ -translation\ binary\ -buffersize\ \$chunkSize\ -encoding\ binary\n\n\ \ \ \ set\ info(unpackSoFar)\ 0\n\ \ \ \ set\ conf(unpackFin)\ \ \ \$fin\n\ \ \ \ set\ conf(unpackFout)\ \ \$fout\n\ \ \ \ unset\ -nocomplain\ info(unpackDone)\n\ \ \ \ unpackfile\ \$fin\ \$fout\ \$chunkSize\ 0\n\ \ \ \ vwait\ ::info(unpackDone)\n\n\ \ \ \ return\ \$dest\n\}\n\nproc\ ::InstallJammer::unpackfile\ \{in\ out\ size\ bytes\ \{error\ \"\"\}\}\ \{\n\ \ \ \ global\ info\n\n\ \ \ \ if\ \{!\[PauseCheck\]\}\ \{\n\ \ \ \ \ \ \ \ set\ error\ \"Install\ Stopped\"\n\ \ \ \ \}\n\n\ \ \ \ IncrProgress\ \$bytes\n\n\ \ \ \ if\ \{\[string\ length\ \$error\]\ ||\ \[eof\ \$in\]\}\ \{\n\tclose\ \$in\n\tclose\ \$out\n\tset\ info(unpackDone)\ \$info(unpackTotal)\n\ \ \ \ \}\ else\ \{\n\t::fcopy\ \$in\ \$out\ -size\ \$size\ \\\n\t\ \ \ \ -command\ \[list\ ::InstallJammer::unpackfile\ \$in\ \$out\ \$size\]\n\ \ \ \ \}\n\}\n\nproc\ ::InstallJammer::InstallLog\ \{\ string\ \}\ \{\n\ \ \ \ output\ \[list\ :LOG\ \$string\]\n\}\n\nproc\ ::InstallJammer::exit\ \{\}\ \{\n\ \ \ \ global\ info\n\ \ \ \ global\ conf\n\n\ \ \ \ if\ \{!\$conf(threaded)\}\ \{\n\ \ \ \ \ \ \ \ ::InstallJammer::WriteDoneFile\ \$info(Temp)\n\n\ \ \ \ \ \ \ \ catch\ \{\ close\ \$conf(runlogFp)\ \}\n\ \ \ \ \ \ \ \ catch\ \{\ close\ \$conf(unpackFin)\ \ \}\n\ \ \ \ \ \ \ \ catch\ \{\ close\ \$conf(unpackFout)\ \}\n\n\ \ \ \ \ \ \ \ ::exit\n\ \ \ \ \}\n\n\ \ \ \ output\ :DONE\n\}\n\nproc\ ::InstallJammer::UnpackMain\ \{\}\ \{\n\ \ \ \ global\ info\n\ \ \ \ global\ conf\n\n\ \ \ \ catch\ \{\ wm\ withdraw\ .\ \}\n\n\ \ \ \ set\ conf(pwd)\ \[file\ dirname\ \[info\ nameofexe\]\]\n\n\ \ \ \ if\ \{!\[info\ exists\ ::tcl_platform(threaded)\]\}\ \{\n\ \ \ \ \ \ \ \ set\ info(Temp)\ \$conf(pwd)\n\ \ \ \ \ \ \ \ uplevel\ #0\ \[list\ source\ \[file\ join\ \$conf(pwd)\ unpack.ini\]\]\n\ \ \ \ \}\n\n\ \ \ \ ::InstallJammer::CommonInit\n\n\ \ \ \ set\ conf(stop)\ \ \[TmpDir\ .stop\]\n\ \ \ \ set\ conf(pause)\ \[TmpDir\ .pause\]\n\n\ \ \ \ ::InstallJammer::InitSetup\n\ \ \ \ ::InstallJammer::InitFiles\n\n\ \ \ \ if\ \{!\[info\ exists\ ::tcl_platform(threaded)\]\}\ \{\n\ \ \ \ \ \ \ \ set\ conf(vfs)\ /installkitunpackvfs\n\ \ \ \ \ \ \ \ ::installkit::Mount\ \$info(installer)\ \$conf(vfs)\n\ \ \ \ \ \ \ \ set\ conf(runlogFp)\ \[open\ \[TmpDir\ run.log\]\ w\]\n\ \ \ \ \}\n\n\ \ \ \ set\ conf(rollback)\ \[string\ match\ \"*Rollback*\"\ \$info(CancelledInstallAction)\]\n\n\ \ \ \ ::InstallJammer::InstallFiles\n\n\ \ \ \ ::InstallJammer::exit\n\}\n\n::InstallJammer::UnpackMain\n}
  14780.  
  14781. proc RaiseStep { wizard id } {
  14782. if {![string length [::InstallJammer::GetText $id Caption]]} {
  14783. grid remove [$id widget get Caption]
  14784. } else {
  14785. grid [$id widget get Caption]
  14786. }
  14787.  
  14788. if {![string length [::InstallJammer::GetText $id Message]]} {
  14789. grid remove [$id widget get Message]
  14790. } else {
  14791. grid [$id widget get Message]
  14792. }
  14793.  
  14794. if {[string length [$id widget get ClientArea]]} {
  14795. grid configure $wizard.buttons -pady {18 5}
  14796. } else {
  14797. grid configure $wizard.buttons -pady 5
  14798. }
  14799. }
  14800.  
  14801. proc CreateWindow.License {wizard id} {
  14802.     CreateWindow.CustomTextPane1 $wizard $id
  14803.  
  14804.     if {![$id get UserMustAcceptLicense]} { return }
  14805.  
  14806.     set base [$id widget get ClientArea]
  14807.  
  14808.    ttk::radiobutton $base.accept -variable ::info(LicenseAccepted) -value 1  -command [list $wizard itemconfigure next -state normal]
  14809.    grid $base.accept -row 1 -column 0 -sticky w
  14810.    $id widget set AcceptRadiobutton -widget $base.accept
  14811.  
  14812.     ttk::radiobutton $base.decline -variable ::info(LicenseAccepted) -value 0  -command [list $wizard itemconfigure next -state disabled]
  14813.     grid $base.decline -row 2 -column 0 -sticky w
  14814.     $id widget set DeclineRadiobutton -widget $base.decline
  14815. }
  14816.  
  14817. proc CreateWindow.CopyFiles {wizard id} {
  14818.     CreateWindow.CustomBlankPane2 $wizard $id
  14819.  
  14820.     set base [$id widget get ClientArea]
  14821.  
  14822.     grid rowconfigure    $base 0 -weight 1
  14823.     grid columnconfigure $base 0 -weight 1
  14824.  
  14825.     set frame [frame $base.frame]
  14826.     grid $frame -row 0 -column 0 -sticky new
  14827.  
  14828.     grid rowconfigure    $frame 1 -weight 1
  14829.     grid columnconfigure $frame 0 -weight 1
  14830.  
  14831.     Label $frame.file -anchor w -elide 1 -ellipsis {[...]} -elideside center
  14832.     grid  $frame.file -row 0 -column 0 -sticky new -padx [list 0 10]
  14833.     $id widget set FileLabel -widget $frame.file
  14834.  
  14835.     ttk::progressbar $frame.progress
  14836.     grid $frame.progress -row 1 -column 0 -sticky ew
  14837.     $id widget set ProgressValue -widget $frame.progress -type progress
  14838. }
  14839.  
  14840. proc CreateWindow.SetupComplete {wizard id} {
  14841.     CreateWindow.CustomBlankPane1 $wizard $id
  14842. }
  14843.  
  14844. proc CreateWindow.CopyFiles {wizard id} {
  14845.     CreateWindow.CustomBlankPane2 $wizard $id
  14846.  
  14847.     set base [$id widget get ClientArea]
  14848.  
  14849.     grid rowconfigure    $base 0 -weight 1
  14850.     grid columnconfigure $base 0 -weight 1
  14851.  
  14852.     set frame [frame $base.frame]
  14853.     grid $frame -row 0 -column 0 -sticky new
  14854.  
  14855.     grid rowconfigure    $frame 1 -weight 1
  14856.     grid columnconfigure $frame 0 -weight 1
  14857.  
  14858.     Label $frame.file -anchor w -elide 1 -ellipsis {[...]} -elideside center
  14859.     grid  $frame.file -row 0 -column 0 -sticky new -padx [list 0 10]
  14860.     $id widget set FileLabel -widget $frame.file
  14861.  
  14862.     ttk::progressbar $frame.progress
  14863.     grid $frame.progress -row 1 -column 0 -sticky ew
  14864.     $id widget set ProgressValue -widget $frame.progress -type progress
  14865. }
  14866.  
  14867. proc CreateWindow.SelectDestination {wizard id} {
  14868.     variable info
  14869.  
  14870.     CreateWindow.CustomBlankPane2 $wizard $id
  14871.  
  14872.     set base [$id widget get ClientArea]
  14873.  
  14874.     grid rowconfigure    $base 0 -weight 1
  14875.     grid columnconfigure $base 0 -weight 1
  14876.  
  14877.     labelframe $base.frame -relief groove -bd 2
  14878.     grid $base.frame -row 0 -column 0 -sticky sew
  14879.     $id widget set DestinationLabel -widget $base.frame
  14880.  
  14881.     grid rowconfigure    $base.frame 0 -weight 1
  14882.     grid columnconfigure $base.frame 0 -weight 1
  14883.  
  14884.     Label $base.frame.destination -anchor nw -textvariable ::info(InstallDir)  -elide 1 -elideside center -ellipsis {[...]}
  14885.     grid  $base.frame.destination -row 0 -column 0 -sticky ew -padx 5 -pady 3
  14886.  
  14887.     Button $base.frame.browse -command ::InstallJammer::SetInstallDir
  14888.     grid $base.frame.browse -row 0 -column 1 -sticky nw -padx 5 -pady [list 0 5]
  14889.     $id widget set BrowseButton -widget $base.frame.browse
  14890. }
  14891.  
  14892. proc CreateWindow.SetupComplete {wizard id} {
  14893.     CreateWindow.CustomBlankPane1 $wizard $id
  14894. }
  14895.  
  14896. proc CreateWindow.StartCopyingFiles {wizard id} {
  14897.     CreateWindow.CustomTextPane1 $wizard $id
  14898.  
  14899.     set text [$id widget get Text]
  14900.     $text configure -bg [style configure . -background]
  14901. }
  14902.  
  14903. proc CreateWindow.Welcome {wizard id} {
  14904.     CreateWindow.CustomBlankPane1 $wizard $id
  14905. }
  14906.  
  14907. proc CreateWindow.CustomTextPane1 {wizard id} {
  14908.     CreateWindow.CustomBlankPane2 $wizard $id
  14909.  
  14910.     set base [$id widget get ClientArea]
  14911.  
  14912.     grid rowconfigure    $base 0 -weight 1
  14913.     grid columnconfigure $base 0 -weight 1
  14914.  
  14915.     frame $base.frame
  14916.     grid  $base.frame -row 0 -column 0 -sticky news
  14917.     
  14918.     grid rowconfigure    $base.frame 0 -weight 1
  14919.     grid columnconfigure $base.frame 0 -weight 1
  14920.  
  14921.     if {![$id get TextFont font]} { set font TkTextFont }
  14922.  
  14923.     text $base.frame.text  -bg white -font $font -wrap word -highlightthickness 0  -yscrollcommand "$base.frame.vs set"  -xscrollcommand "$base.frame.hs set"
  14924.     grid $base.frame.text -row 0 -column 0 -sticky news
  14925.     $id widget set Text -widget $base.frame.text
  14926.  
  14927.     ttk::scrollbar $base.frame.vs -command "$base.frame.text yview"
  14928.     grid $base.frame.vs -row 0 -column 1 -sticky ns
  14929.  
  14930.     ttk::scrollbar $base.frame.hs -command "$base.frame.text xview"  -orient horizontal
  14931.     grid $base.frame.hs -row 1 -column 0 -sticky ew
  14932. }
  14933.  
  14934. proc CreateWindow.CustomBlankPane2 {wizard id} {
  14935.     set base  [$wizard widget get $id]
  14936.     set frame $base.titleframe
  14937.  
  14938.     grid rowconfigure    $base 3 -weight 1
  14939.     grid columnconfigure $base 0 -weight 1
  14940.  
  14941.     frame $frame -bd 0 -relief flat -background white
  14942.     grid  $frame -row 0 -column 0 -sticky nsew
  14943.  
  14944.     grid rowconfigure    $frame 1 -weight 1
  14945.     grid columnconfigure $frame 0 -weight 1
  14946.  
  14947.     Label $frame.title -background white -anchor nw -justify left -autowrap 1  -font TkCaptionFont -textvariable [$wizard variable $id -text1]
  14948.     grid $frame.title -row 0 -column 0 -sticky new -padx 5 -pady 5
  14949.     $id widget set Title -widget $frame.title
  14950.  
  14951.     Label $frame.subtitle -background white -anchor nw -autowrap 1  -justify left -textvariable [$wizard variable $id -text2]
  14952.     grid $frame.subtitle -row 1 -column 0 -sticky new -padx [list 20 5]
  14953.     $id widget set Subtitle -widget $frame.subtitle
  14954.  
  14955.     label $frame.icon -borderwidth 0 -background white -anchor c
  14956.     grid  $frame.icon -row 0 -column 1 -rowspan 2
  14957.     $id widget set Icon -widget $frame.icon -type image
  14958.  
  14959.     Separator $base.separator -relief groove -orient horizontal
  14960.     grid $base.separator -row 1 -column 0 -sticky ew 
  14961.  
  14962.     Label $base.caption -anchor nw -justify left -autowrap 1  -textvariable [$wizard variable $id -text3]
  14963.     grid $base.caption -row 2 -sticky nsew -padx 8 -pady [list 8 4]
  14964.     $id widget set Caption -widget $base.caption
  14965.  
  14966.     frame $base.clientarea
  14967.     grid  $base.clientarea -row 3 -sticky nsew -padx 8 -pady 4
  14968.     $id widget set ClientArea -widget $base.clientarea -type frame
  14969.  
  14970.     Label $base.message -anchor nw -justify left -autowrap 1  -textvariable [$wizard variable $id -text4]
  14971.     grid $base.message -row 4 -sticky nsew -padx 8 -pady [list 4 8]
  14972.     $id widget set Message -widget $base.message
  14973. }
  14974.  
  14975. proc CreateWindow.CustomBlankPane1 {wizard id} {
  14976.     set base [$wizard widget get $id]
  14977.  
  14978.     grid rowconfigure    $base 1 -weight 1
  14979.     grid columnconfigure $base 1 -weight 1
  14980.  
  14981.     label $base.image -borderwidth 0
  14982.     grid  $base.image -row 0 -column 0 -rowspan 2 -sticky nw
  14983.     $id widget set Image -type image -widget $base.image
  14984.  
  14985.     Label $base.title -height 3 -bg white -font TkCaptionFont  -autowrap 1 -anchor nw -justify left
  14986.     grid $base.title -row 0 -column 1 -sticky ew -padx 20 -pady [list 20 10]
  14987.     $id widget set Caption -type text -widget $base.title
  14988.  
  14989.     Label $base.message -bg white -autowrap 1 -anchor nw -justify left
  14990.     grid  $base.message -row 1 -column 1 -sticky news -padx 20
  14991.     $id widget set Message -type text -widget $base.message
  14992.  
  14993.     Separator $base.sep -orient horizontal
  14994.     grid $base.sep -row 2 -column 0 -columnspan 2 -sticky ew
  14995. }
  14996.  
  14997.  
  14998.  
  14999. proc ThemeInit {} {
  15000. variable info
  15001.  
  15002. Wizard $info(Wizard) -width 500 -height 365  -raisecommand  [list RaiseStep %W %S]  -separatortext "Check n Do"  -title [::InstallJammer::SubstText "<%AppName%> Setup"]
  15003.  
  15004. if {$::tcl_platform(platform) eq "unix"} {
  15005. $info(Wizard) configure -bg [style configure . -background]
  15006. }
  15007. }
  15008.  
  15009.  
  15010.  
  15011. if {[info exists ::InstallJammer]} { return }
  15012.  
  15013. proc ::InstallJammer::UpdateInstallInfo {} {
  15014. global info
  15015.  
  15016. set info(SpaceRequired)      0
  15017. set info(SelectedComponents) [list]
  15018. set info(SelectedFileGroups) [list]
  15019.  
  15020. set required 0
  15021. foreach setuptype [SetupTypes children] {
  15022. if {![$setuptype active]} { continue }
  15023.  
  15024. foreach component [$setuptype get Components] {
  15025. if {![$component active]} { continue }
  15026.  
  15027. set name [$component name]
  15028. if {[lsearch -exact $info(SelectedComponents) $name] < 0} {
  15029. lappend info(SelectedComponents) $name
  15030. }
  15031.  
  15032. foreach filegroup [$component get FileGroups] {
  15033. if {![$filegroup active]} { continue }
  15034.  
  15035. incr required [$filegroup get Size]
  15036.  
  15037. set name [$filegroup name]
  15038. if {[lsearch -exact $info(SelectedFileGroups) $name] < 0} {
  15039. lappend info(SelectedFileGroups) $name
  15040. }
  15041. }
  15042. }
  15043. }
  15044.  
  15045. set info(SpaceRequired) $required
  15046.  
  15047. ::InstallJammer::UpdateWidgets
  15048. }
  15049.  
  15050. proc ::InstallJammer::PopulateComponents { step } {
  15051. global info
  15052.  
  15053. set tree [$step widget get ComponentTree]
  15054. set text [$step widget get DescriptionText]
  15055.  
  15056. set setuptype [::InstallJammer::FindObjByName Custom [SetupTypes children]]
  15057.  
  15058. if {![string length $setuptype]} { return }
  15059.  
  15060. foreach id [$setuptype get Components] {
  15061. if {![$id get ShowComponent]} { continue }
  15062.  
  15063. set parent [$id parent]
  15064. if {$parent eq "Components"} { set parent root }
  15065.  
  15066. $tree insert end $parent $id -text [$id name] -image checkon
  15067.  
  15068. if {[$id get RequiredComponent]} {
  15069. $tree itemconfigure $id -fill SystemDisabledText
  15070. }
  15071.  
  15072. if {![info exists node]} { set node $id }
  15073. }
  15074.  
  15075. $tree selection set $node
  15076.  
  15077. set desc [::InstallJammer::GetText $node Description]
  15078. ::InstallJammer::SetText $text $desc
  15079. ::InstallJammer::SetVirtualText $info(Language) $step  [list DescriptionText $desc]
  15080. }
  15081.  
  15082. proc ::InstallJammer::SelectComponent { node } {
  15083. global info
  15084.  
  15085. set id   [$info(Wizard) raise]
  15086. set tree [$id widget get ComponentTree]
  15087. set text [$id widget get DescriptionText]
  15088. set desc [::InstallJammer::GetText $node Description]
  15089.  
  15090. $tree selection set $node
  15091.  
  15092. ::InstallJammer::SetText $text $desc
  15093.  
  15094. ::InstallJammer::SetVirtualText $info(Language) $id  [list DescriptionText $desc]
  15095.  
  15096. ::InstallJammer::UpdateInstallInfo
  15097. }
  15098.  
  15099. proc ::InstallJammer::ToggleComponent { node } {
  15100. global info
  15101.  
  15102. set id   [$info(Wizard) raise]
  15103. set tree [$id widget get ComponentTree]
  15104.  
  15105. if {[$node get RequiredComponent]} { return }
  15106.  
  15107. if {[$node active]} {
  15108. $node active 0
  15109. $tree itemconfigure $node -image checkoff
  15110.  
  15111. foreach component [$node children recursive] {
  15112. $component active 0
  15113. if {[$tree exists $component]} {
  15114. $tree itemconfigure $component -image checkoff
  15115. }
  15116. }
  15117. } else {
  15118. $node active 1
  15119. $tree itemconfigure $node -image checkon
  15120.  
  15121. foreach component [$node children recursive] {
  15122. $component active 1
  15123. if {[$tree exists $component]} {
  15124. $tree itemconfigure $component -image checkon
  15125. }
  15126. }
  15127. }
  15128.  
  15129. ::InstallJammer::UpdateInstallInfo
  15130. }
  15131.  
  15132. proc ::InstallJammer::PopulateSetupTypes { step } {
  15133. global info
  15134.  
  15135. set text    [$step widget get DescriptionText]
  15136. set listbox [$step widget get SetupTypeListBox]
  15137.  
  15138. foreach id [SetupTypes children] {
  15139. if {![$id active]} { continue }
  15140. $listbox insert end $id -text [$id name] -data [$id name]
  15141. if {[$id name] eq $info(InstallType)} {
  15142. $listbox selection set $id
  15143. set desc [::InstallJammer::GetText $id Description]
  15144. ::InstallJammer::SetText $text $desc
  15145. ::InstallJammer::SetVirtualText $info(Language) $step  [list DescriptionText $desc]
  15146. }
  15147. }
  15148. }
  15149.  
  15150. proc ::InstallJammer::SelectSetupType { {node ""} } {
  15151. global info
  15152.  
  15153. if {[string length $node]} {
  15154. set info(InstallType) [$node name]
  15155.  
  15156. set id   [$info(Wizard) raise]
  15157. set text [$id widget get DescriptionText]
  15158. set desc [::InstallJammer::GetText $node Description]
  15159.  
  15160. ::InstallJammer::SetText $text $desc
  15161.  
  15162. ::InstallJammer::SetVirtualText $info(Language) $id  [list DescriptionText $desc]
  15163.  
  15164. set list [$id widget get SetupTypeListBox]
  15165. $list selection set $node
  15166. }
  15167.  
  15168. if {![string equal $info(InstallType) "Custom"]} {
  15169. foreach setuptype [SetupTypes children] {
  15170. if {[string equal [$setuptype name] $info(InstallType)]} {
  15171. $setuptype active 1
  15172. } else {
  15173. $setuptype active 0
  15174. }
  15175. }
  15176. }
  15177.  
  15178. ::InstallJammer::UpdateInstallInfo
  15179. }
  15180.  
  15181. proc ::InstallJammer::PopulateProgramFolders { step } {
  15182. global conf
  15183.  
  15184. set listbox [$step widget get ProgramFolderListBox]
  15185.  
  15186. if {$conf(windows)} {
  15187. set folder [list]
  15188. foreach dir {PROGRAMS COMMON_PROGRAMS} {
  15189. set dir [::InstallJammer::WindowsDir $dir]
  15190. eval lappend folders [glob -nocomplain -type d -dir $dir -tails *]
  15191. }
  15192. eval [list $listbox insert end] [lsort -dict -unique $folders]
  15193. }
  15194. }
  15195.  
  15196. proc ::InstallJammer::SetProgramFolder { {folder ""} } {
  15197. global conf
  15198. global info
  15199.  
  15200. if {![string length $folder]} {
  15201. set step $info(CurrentPane)
  15202. set listbox [$step widget get ProgramFolderListBox]
  15203. set folder  [$listbox get [$listbox curselection]]
  15204.  
  15205. set list [file split $info(OriginalProgramFolderName)]
  15206. if {[llength $list] > 1} {
  15207. set folder [file join $folder [lindex $list end]]
  15208. } else {
  15209. set folder [file join $folder $info(OriginalProgramFolderName)]
  15210. }
  15211. }
  15212.  
  15213. set info(ProgramFolderName) $folder
  15214.  
  15215. if {!$info(ProgramFolderAllUsers)} {
  15216. set info(ProgramFolder) "<%PROGRAMS%>/<%ProgramFolderName%>"
  15217. } else {
  15218. set info(ProgramFolder) "<%COMMON_PROGRAMS%>/<%ProgramFolderName%>"
  15219. }
  15220. }
  15221.  
  15222. proc ::InstallJammer::ScrollLicenseTextBox { force args } {
  15223. global info
  15224.  
  15225. eval $args
  15226.  
  15227. if {!$force} { return }
  15228.  
  15229. set w   [lindex $args 0]
  15230. lassign [$w yview] y0 y1
  15231.  
  15232. if {$y1 == 1} {
  15233. $info(Wizard) itemconfigure next -state normal
  15234. } else {
  15235. $info(Wizard) itemconfigure next -state disabled
  15236. }
  15237. }
  15238.  
  15239. proc ::InstallJammer::exit { {prompt 0} } {
  15240. global conf
  15241. global info
  15242.  
  15243. if {$prompt} {
  15244. ::InstallJammer::PauseInstall
  15245.  
  15246. set title   "Exit Setup"
  15247. set message [::InstallJammer::SubstText "<%ExitText%>"]
  15248. set ans [MessageBox -type yesno  -parent [::InstallJammer::TransientParent]  -title $title -message $message]
  15249.  
  15250. if {$ans eq "no"} {
  15251. ::InstallJammer::ContinueInstall
  15252. return
  15253. }
  15254.  
  15255. set id   [$info(Wizard) raise]
  15256. set when "After Pane is Cancelled"
  15257.  
  15258. ::InstallJammer::ExecuteActions $id -when $when
  15259.  
  15260. if {![$id checkConditions $when]} { return }
  15261.  
  15262. set info(InstallCancelled) 1
  15263. }
  15264.  
  15265. if {$info(Installing)} {
  15266. ::InstallJammer::StopInstall
  15267.  
  15268. tkwait variable ::info(Installing)
  15269.  
  15270. if {[string match "*Continue*" $info(CancelledInstallAction)]} {
  15271. }
  15272. }
  15273.  
  15274. if {$info(InstallStopped) && $info(InstallStarted)
  15275. && $info(CleanupCancelledInstall)} {
  15276. ::InstallJammer::CleanupCancelledInstall
  15277. }
  15278.  
  15279. if {($info(WizardStarted)||$info(SilentMode)) && !$info(InstallCancelled)} {
  15280. ::InstallJammer::ExecuteActions "Finish Actions"
  15281.  
  15282. if {!$info(InstallStopped)} {
  15283. ::InstallJammer::LogFile [TmpDir install.log]
  15284. ::InstallJammer::LogFile [InstallInfoDir install.log]
  15285. ::InstallJammer::CreateInstallLog [TmpDir install.log]
  15286. ::InstallJammer::CreateInstallLog [InstallInfoDir install.log]
  15287.  
  15288. ::InstallJammer::StoreInstallLogInUninstall
  15289. }
  15290. } else {
  15291. ::InstallJammer::ExecuteActions "Cancel Actions"
  15292. }
  15293.  
  15294. ::InstallJammer::CleanupTmpDirs
  15295.  
  15296. if {!$conf(debugging)} {
  15297. if {[catch { file delete -force $info(Temp) } error]} {
  15298. ::InstallJammer::WriteDoneFile $info(Temp)
  15299. }
  15300. } else {
  15301. if {[info exists ::debugfp]} { close $::debugfp }
  15302. }
  15303.  
  15304. catch { destroy . }
  15305. ::exit
  15306. }
  15307.  
  15308. proc ::InstallJammer::StoreInstallLogInUninstall {} {
  15309. global conf
  15310. if {[info exists conf(uninstall)]} {
  15311. zlib::minizip -append 1 $conf(uninstall)  [list [TmpDir install.log]] [list install.log]
  15312. }
  15313. }
  15314.  
  15315. proc ::InstallJammer::CheckInstallDir { {dir ""} } {
  15316. global info
  15317.  
  15318. if {![string length $dir]} { set dir $info(InstallDir) }
  15319.  
  15320. while {![file exists $dir]} {
  15321. set dir [file dirname $dir]
  15322. }
  15323.  
  15324. set info(Dir) $dir
  15325. set result [::InstallJammer::DirIsWritable $dir]
  15326. if {!$result} {
  15327. ::InstallJammer::MessageBox -title "Error" -message  [::InstallJammer::SubstText "<%DirectoryPermissionText%>"]
  15328. }
  15329. return $result
  15330. }
  15331.  
  15332. proc ::InstallJammer::SetInstallDir { {dir ""} } {
  15333. global conf
  15334. global info
  15335.  
  15336. if {![string length $dir]} {
  15337. set dir [::InstallJammer::ChooseDirectory -initialdir $info(InstallDir)]
  15338. if {![string length $dir]} { return }
  15339. } else {
  15340. set dir [::InstallJammer::SubstText $dir]
  15341. }
  15342.  
  15343. if {![CheckInstallDir $dir]} { return }
  15344.  
  15345. if {$conf(windows) && [file exists $dir]} {
  15346. set dir [file attributes $dir -longname]
  15347. }
  15348.  
  15349. set info(InstallDir) [Normalize $dir $::tcl_platform(platform)]
  15350. }
  15351.  
  15352. proc ::InstallJammer::UnpackOutput { line } {
  15353. global conf
  15354. global info
  15355.  
  15356. if {[string index $line 0] != ":"} { return }
  15357.  
  15358. switch -- [lindex $line 0] {
  15359. ":DONE" {
  15360. set info(FileBeingInstalled)  ""
  15361. set info(GroupBeingInstalled) ""
  15362.  
  15363. set info(Status) "File installation complete..."
  15364.  
  15365. if {[info exists ::tcl_platform(threaded)]} {
  15366. } else {
  15367. catch { close $conf(UnpackFp) }
  15368. }
  15369. set info(Installing) 0
  15370. }
  15371.  
  15372. ":LOG" {
  15373. ::InstallJammer::InstallLog [lindex $line 1]
  15374. }
  15375.  
  15376. ":GROUP" {
  15377. set info(GroupBeingInstalled) [lindex $line 1]
  15378. }
  15379.  
  15380. ":FILE" {
  15381. set file [lindex $line 1]
  15382. set info(FileBeingInstalled) $file
  15383. ::InstallJammer::SetVersionInfo $file [lindex $line 2]
  15384. }
  15385.  
  15386. ":PERCENT" {
  15387. set info(InstallPercentComplete) [lindex $line 1]
  15388. }
  15389.  
  15390. ":FILEPERCENT" {
  15391. set info(FilePercentComplete) [lindex $line 1]
  15392. }
  15393. }
  15394.  
  15395. ::InstallJammer::UpdateWidgets -buttons 0 -updateidletasks 1
  15396. }
  15397.  
  15398. proc ::InstallJammer::ReadUnpack { id } {
  15399. global conf
  15400. global info
  15401.  
  15402. if {[eof $conf(UnpackFp)]} {
  15403. catch { close $conf(UnpackFp) }
  15404. set info(Installing) 0
  15405. return
  15406. }
  15407.  
  15408. gets $conf(UnpackFp) line
  15409.  
  15410. ::InstallJammer::UnpackOutput $line
  15411. }
  15412.  
  15413. proc ::InstallJammer::BuildUnpackInfo { groupList groupArray } {
  15414. global info
  15415. global versions
  15416.  
  15417. upvar 1 $groupArray groups
  15418.  
  15419. ::InstallJammer::ReadInfo
  15420.  
  15421. set unpack [TmpDir unpack.ini]
  15422.  
  15423. set fp [open $unpack w]
  15424.  
  15425. puts $fp "set info(installer) [list [info nameofexecutable]]"
  15426. puts $fp "array set info [list [array get info]]"
  15427. puts $fp "set groups [list $groupList]"
  15428. puts $fp "array set files [list [array get groups]]"
  15429. puts $fp ""
  15430. puts $fp "array set versions [list [array get versions]]"
  15431.  
  15432. puts -nonewline $fp "array set ::InstallJammer::Properties "
  15433. puts $fp "[list [array get ::InstallJammer::Properties]]"
  15434.  
  15435. close $fp
  15436.  
  15437. return $unpack
  15438. }
  15439.  
  15440. proc ::InstallJammer::BuildUnpack {} {
  15441. global info
  15442. global conf
  15443.  
  15444. if {[info exists conf(UnpackBin)]} { return $conf(UnpackBin) }
  15445.  
  15446. set unpack [TmpDir unpack.tcl]
  15447. set conf(UnpackScript) $unpack
  15448.  
  15449. set fp [open $unpack w]
  15450. foreach file {common.tcl files.tcl setup.tcl conditions.tcl unpack.tcl} {
  15451. puts $fp $::InstallJammer::files($file)
  15452. }
  15453. close $fp
  15454.  
  15455. return $unpack
  15456. }
  15457.  
  15458. proc ::InstallJammer::CleanupCancelledInstall {} {
  15459. global conf
  15460. global info
  15461.  
  15462. set info(Status) "Cleaning up install..."
  15463. ::InstallJammer::UpdateWidgets -update 1
  15464.  
  15465. if {![llength $conf(LOG)]} { return }
  15466.  
  15467. for {set i [llength $conf(LOG)]} {$i >= 0} {incr i -1} {
  15468. set line [lindex $conf(LOG) $i]
  15469. set type [lindex $line 0]
  15470. set args [lrange $line 1 end]
  15471. switch -- [lindex $line 0] {
  15472. ":FILE"    {
  15473. set file [lindex $args 0]
  15474. set roll [::InstallJammer::RollbackName $file]
  15475. if {[file exists $roll]} {
  15476. file rename -force $roll $file
  15477. } else {
  15478. eval UninstallFile $args
  15479. }
  15480. }
  15481.  
  15482. ":DIR"    {
  15483. eval UninstallDirectory $args
  15484. }
  15485.  
  15486. ":REGISTRY"    {
  15487. eval UninstallRegistryKey $args
  15488. }
  15489. }
  15490. }
  15491. }
  15492.  
  15493. proc ::InstallJammer::CreateInstallLog { {file ""} } {
  15494. global conf
  15495. global info
  15496.  
  15497. if {![string length $file]} { set file [TmpDir install.log] }
  15498.  
  15499. if {[catch { open $file w } fp]} { return }
  15500.  
  15501. ::InstallJammer::LogFile $file
  15502.  
  15503. set lines [list ":DIR [list $info(InstallDir)]"]
  15504.  
  15505. if {[info exists conf(PREVLOG)]} {
  15506. eval lappend lines $conf(PREVLOG)
  15507. }
  15508.  
  15509. eval lappend lines $conf(LOG)
  15510.  
  15511. foreach line $lines {
  15512. if {![info exists done($line)]} {
  15513. set done($line) 1
  15514. puts $fp $line
  15515. }
  15516. }
  15517. close $fp
  15518. }
  15519.  
  15520. proc ::InstallJammer::InstallLog {string} {
  15521. lappend ::conf(LOG) $string
  15522. }
  15523.  
  15524. proc ::InstallJammer::LogRegistry {key {value ""}} {
  15525. set string "[list $key]"
  15526. if {![lempty $value]} { append string " [list $value]" }
  15527. InstallLog ":REGISTRY $string"
  15528. }
  15529.  
  15530. proc ::InstallJammer::ReadPreviousInstall {} {
  15531. global conf
  15532. global info
  15533.  
  15534. if {[info exists conf(PREVLOG)]} { return }
  15535.  
  15536.  
  15537. set uninstall [file join $info(InstallDir) uninstall$info(Ext)]
  15538.  
  15539. if {[file exists $uninstall]} {
  15540. set dir [::installkit::Mount $uninstall /installkittmpvfs]
  15541. set log [file join $dir install.log]
  15542. if {[file exists $log]} {
  15543. eval lappend conf(PREVLOG) [split [string trim [read_file $log]] \n]
  15544. }
  15545. ::installkit::Unmount $dir
  15546. }
  15547.  
  15548. set dir  [::InstallJammer::GetInstallInfoDir]
  15549. set file [file join $dir install.log]
  15550.  
  15551. if {[file exists $file]} {
  15552. eval lappend conf(PREVLOG) [split [string trim [read_file $file]] \n]
  15553. }
  15554.  
  15555. if {[info exists conf(PREVLOG)]} {
  15556. set info(PreviousInstallExists) 1
  15557. foreach x $conf(PREVLOG) {
  15558. if {[lindex $x 0] eq ":DIR"} {
  15559. set info(PreviousInstallDir) [lindex $x 1]
  15560. break
  15561. }
  15562. }
  15563. }
  15564. }
  15565.  
  15566. proc ::InstallJammer::StoreInfo { dir {mode w} } {
  15567. global info
  15568. global versions
  15569.  
  15570. set file [file join $dir .installinfo]
  15571.  
  15572. set fp [open $file $mode]
  15573.  
  15574. ::InstallJammer::LogFile $file
  15575.  
  15576. foreach file [array names versions] {
  15577. puts $fp "Ver [list $file] $versions($file)"
  15578. }
  15579.  
  15580. close $fp
  15581. }
  15582.  
  15583. proc ::InstallJammer::ReadInfo {} {
  15584. global info
  15585. global versions
  15586.  
  15587. set filename .installinfo
  15588.  
  15589. set file [::InstallJammer::InstallInfoDir $filename]
  15590. if {![file exists $file]} {
  15591. set file [file join $info(InstallDir) $filename]
  15592. }
  15593.  
  15594. if {[file exists $file]} {
  15595. set fp [open $file]
  15596.  
  15597. while {[gets $fp line] != -1} {
  15598. switch -- [lindex $line 0] {
  15599. "Ver" {
  15600. lassign $line cmd file ver
  15601. set versions($file) $ver
  15602. }
  15603. }
  15604. }
  15605.  
  15606. close $fp
  15607. }
  15608. }
  15609.  
  15610. proc ::InstallJammer::InstallComponentsTotalSize {} {
  15611. global info
  15612.  
  15613. if {![info exists info(InstallComponents)]} { return 0 }
  15614.  
  15615. set size 0
  15616. foreach list $info(InstallComponents) {
  15617. switch -- [lindex $list 0] {
  15618. "Wrapped Script" {
  15619. iincr size [file size [::installkit::base]]
  15620. }
  15621.  
  15622. "Wrapped Application" {
  15623. iincr size [file size $info(Installer)]
  15624. }
  15625. }
  15626. }
  15627. return $size
  15628. }
  15629.  
  15630. proc ::InstallJammer::ParseCommandLineArguments { arglist } {
  15631. global conf
  15632. global info
  15633.  
  15634. set len [llength $arglist]
  15635. for {set i 0} {$i < $len} {incr i} {
  15636. set opt [lindex $arglist $i]
  15637.  
  15638. switch -glob -- $opt {
  15639. "-C" {
  15640. if {!$info(IncludeDebugging)} { continue }
  15641. if {!$conf(windows)} { SourceCachedFile console.tcl }
  15642. console show
  15643. }
  15644.  
  15645. "-D" {
  15646. if {!$info(IncludeDebugging)} { continue }
  15647. set conf(debugging) 1
  15648. }
  15649.  
  15650. "-D*" {
  15651. set opt [string range $opt 2 end]
  15652. set val [lindex $arglist [incr i]]
  15653. set info($opt) $val
  15654. }
  15655.  
  15656. "-S" {
  15657. set info(SilentMode)  1
  15658. set info(InstallMode) "Silent"
  15659. }
  15660.  
  15661. "-T" {
  15662. if {!$info(IncludeDebugging)} { continue }
  15663. set conf(testing) 1
  15664. }
  15665.  
  15666. "-V" {
  15667. set app $info(AppName)
  15668. set ver $info(Version)
  15669. set title "InstallJammer Installer version $conf(version)"
  15670. set msg [::InstallJammer::SubstText "<%VersionHelpText%>"]
  15671. ::InstallJammer::Message -title $title -message $msg
  15672. ::exit
  15673. }
  15674.  
  15675. "-Y" {
  15676. set info(InstallMode) "Default"
  15677. set info(DefaultMode) 1
  15678. }
  15679.  
  15680. "--prefix" {
  15681. set val [lindex $arglist [incr i]]
  15682. ::InstallJammer::SetInstallDir $val
  15683. }
  15684. }
  15685. }
  15686.  
  15687. set info(GuiMode) [expr {$info(InstallMode) eq "Standard"
  15688. || $info(InstallMode) eq "Default"}]
  15689. }
  15690.  
  15691. proc ::InstallJammer::SourceCachedFile { file {namespace ""} } {
  15692. variable files
  15693. if {![info exists files($file)]} { return 0 }
  15694. if {![string length $namespace]} {
  15695. uplevel #0 $files($file)
  15696. } else {
  15697. namespace eval $namespace $files($file)
  15698. }
  15699. return 1
  15700. }
  15701.  
  15702. proc ::InstallJammer::AskUserLanguage {} {
  15703. global conf
  15704. global info
  15705.  
  15706. variable languages
  15707. variable languagecodes
  15708.  
  15709. set list [::InstallJammer::GetLanguages]
  15710.  
  15711. if {[llength $list] < 1} { return }
  15712.  
  15713. set top .__askLanguage
  15714.  
  15715. Dialog $top -title "Language Selection"
  15716. wm resizable $top 0 0
  15717.  
  15718. set f [$top getframe]
  15719.  
  15720. ttk::label $f.l -text "Please select the installation language"
  15721. pack $f.l -pady 10
  15722.  
  15723. ttk::combobox $f.cb -state readonly  -textvariable ::conf(Language) -values $list
  15724. pack $f.cb
  15725.  
  15726. $top add -text "OK"
  15727. $top add -text "Cancel"
  15728.  
  15729. set conf(Language) $info(Language)
  15730. foreach loc $conf(mclocale) {
  15731. if {[info exists languagecodes($loc)]} {
  15732. set conf(Language) $languagecodes($loc)
  15733. break
  15734. }
  15735. }
  15736.  
  15737. foreach lang [::msgcat::mcpreferences] {
  15738. if {[info exists languagecodes($lang)]} {
  15739. set conf(Language) $languagecodes($lang)
  15740. break
  15741. }
  15742. }
  15743.  
  15744. if {[$top draw] == 1} {
  15745. set info(InstallCancelled) 1
  15746. ::InstallJammer::exit
  15747. }
  15748.  
  15749. set info(Language) $languages($conf(Language))
  15750. ::msgcat::mclocale $info(Language)
  15751. }
  15752.  
  15753. proc ::InstallJammer::InstallMain {} {
  15754. global conf
  15755. global info
  15756.  
  15757. if {$::tcl_platform(platform) eq "unix"} {
  15758. if {$info(RequireRoot) && !$info(UserIsRoot)} {
  15759. ::InstallJammer::Message -title "Root Required" -message  [::InstallJammer::SubstText "<%RequireRootText%>"]
  15760. set info(InstallCancelled) 1
  15761. ::InstallJammer::exit 1
  15762. }
  15763. }
  15764.  
  15765. if {$info(SilentMode)} {
  15766. ::InstallJammer::ExecuteActions "Startup Actions"
  15767. ::InstallJammer::ExecuteActions Silent
  15768. } else {
  15769. BWidget::use ttk 1 -force
  15770.  
  15771. if {$info(AllowLanguageSelection)} {
  15772. ::InstallJammer::AskUserLanguage
  15773. }
  15774.  
  15775. ::InstallJammer::ExecuteActions "Startup Actions"
  15776.  
  15777. set info(WizardStarted) 1
  15778. ::InstallJammer::CenterWindow $info(Wizard)
  15779. raise $info(Wizard)
  15780. ::InstallJammer::Wizard next
  15781. }
  15782. }
  15783.  
  15784. proc ::InstallJammer::InitInstall {} {
  15785. global conf
  15786. global info
  15787.  
  15788. if {[string equal $::tcl_platform(platform) "windows"]} {
  15789. package require Wintcl
  15790. }
  15791.  
  15792. SourceCachedFile gui.tcl
  15793. SourceCachedFile common.tcl
  15794. SourceCachedFile setup.tcl
  15795. SourceCachedFile files.tcl
  15796. SourceCachedFile actions.tcl
  15797. SourceCachedFile conditions.tcl
  15798.  
  15799. ::InstallJammer::CommonInit
  15800.  
  15801. array set conf {
  15802. testing         0
  15803. debugging       0
  15804. }
  15805.  
  15806. set conf(stop)  [::InstallJammer::TmpDir .stop]
  15807. set conf(pause) [::InstallJammer::TmpDir .pause]
  15808.  
  15809. array set info {
  15810. Installing             0
  15811. InstallStarted         0
  15812. InstallStopped         0
  15813. InstallFinished        0
  15814. InstallCancelled       0
  15815. WizardStarted          0
  15816. CommonStartMenu        /etc/X11/applnk
  15817. KDEStartMenu           <%Home%>/.kde/share/applnk
  15818. KDECommonStartMenu     /usr/share/applnk
  15819. GnomeStartMenu         <%Home%>/.gnome/apps
  15820. GnomeCommonStartMenu   /usr/share/gnome/apps
  15821.  
  15822. LicenseAccepted         No
  15823. FileBeingInstalled      ""
  15824. GroupBeingInstalled     ""
  15825. InstallPercentComplete  0
  15826.  
  15827. PreviousInstallDir      ""
  15828. PreviousInstallExists   0
  15829.  
  15830. RunningInstaller        1
  15831. }
  15832.  
  15833. set conf(LOG) [list]
  15834.  
  15835. set conf(rollback) [string match "*Rollback*" $info(CancelledInstallAction)]
  15836.  
  15837. set info(Installer)     $conf(exe)
  15838. set info(InstallID)     [::InstallJammer::uuid]
  15839. set info(InstallSource) [file dirname $conf(exe)]
  15840.  
  15841. ::InstallJammer::ParseCommandLineArguments $::argv
  15842.  
  15843. if {$info(GuiMode)} {
  15844. SourceCachedFile gui.tcl
  15845. InitGui
  15846. }
  15847.  
  15848. ::InstallJammer::InitSetup
  15849. ::InstallJammer::InitFiles
  15850.  
  15851. ::InstallJammer::ReadMessageCatalog messages
  15852.  
  15853. if {$conf(windows)} {
  15854. set key {HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion}
  15855. catch {
  15856. set info(UserInfoName)    [registry get $key RegisteredOwner]
  15857. set info(UserInfoCompany) [registry get $key RegisteredOrganization]
  15858. }
  15859. }
  15860.  
  15861. foreach var [list InstallDir ProgramFolderName] {
  15862. set info($var) [::InstallJammer::SubstText <%$var%>]
  15863. set info(Original$var) $info($var)
  15864. }
  15865.  
  15866. ::InstallJammer::UpdateInstallInfo
  15867.  
  15868. if {$::tcl_platform(platform) eq "unix"} {
  15869. if {$info(RootInstallDir) ne "" && $info(UserIsRoot)} {
  15870. ::InstallJammer::SetInstallDir $info(RootInstallDir)
  15871. }
  15872. }
  15873.  
  15874. ::InstallJammer::LoadTwapi
  15875.  
  15876. if {0 && [info exists ::tcl_platform(threaded)]} {
  15877. set ::tid [installkit::newThread thread::wait]
  15878. thread::send $::tid [list set info(Ext) $info(Ext)]
  15879. thread::send $::tid [list set info(Temp) $info(Temp)]
  15880. thread::send $::tid [list set info(Platform) $info(Platform)]
  15881. thread::send $::tid [list eval $::InstallJammer::files(common.tcl)]
  15882. thread::send $::tid {
  15883. proc BuildInstallkit {} {
  15884. thread::send $::parentThread "set conf(BuildingInstallkit) 1"
  15885. ::installkit::base
  15886. thread::send $::parentThread  "unset -nocomplain conf(BuildingInstallkit)"
  15887. }
  15888. }
  15889. thread::send -async $::tid BuildInstallkit
  15890. }
  15891. }
  15892.  
  15893. ::InstallJammer::InitInstall
  15894.  
  15895. InstallType ::Common
  15896. InstallType ::Standard
  15897. InstallComponent A2E136B8-114D-4028-876B-5F7DE6E5D06C -setup Install -title {Welcome Screen} -component Welcome -type pane -active Yes -parent Standard
  15898. InstallComponent 26169907-3309-4C13-80BA-E6392EFA3702 -setup Install -title {License Agreement} -component License -type pane -active Yes -parent Standard
  15899. InstallComponent EBE76197-B5AB-4228-BA51-F7780EFD5C07 -setup Install -conditions {2F135310-2F98-4A7C-9DC1-ED574350AA47 0509031B-2E3F-4330-B44F-1E1586B0B38F} -title {Modify Widget} -component ModifyWidget -command insert -type action -active Yes -parent 26169907-3309-4C13-80BA-E6392EFA3702
  15900. Condition 2F135310-2F98-4A7C-9DC1-ED574350AA47 -active Yes -parent EBE76197-B5AB-4228-BA51-F7780EFD5C07 -title {String Is Condition} -component StringIsCondition
  15901. Condition 0509031B-2E3F-4330-B44F-1E1586B0B38F -active Yes -parent EBE76197-B5AB-4228-BA51-F7780EFD5C07 -title {Script Condition} -component ScriptCondition
  15902. InstallComponent 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D -setup Install -conditions 376A656F-918F-49E1-9E01-3E734532FA0F -title {Select Destination} -component SelectDestination -command insert -type pane -active Yes -parent Standard
  15903. Condition 376A656F-918F-49E1-9E01-3E734532FA0F -active Yes -parent 9FF9A6C3-9DBB-4F6E-9724-B57973A3745D -title {File Permission Condition} -component FilePermissionCondition
  15904. InstallComponent 7F7C9C19-3650-4E50-8B27-32C9644DF62B -setup Install -title {Start Copying Files} -component StartCopyingFiles -type pane -active Yes -parent Standard
  15905. InstallComponent 354BBA54-2679-44CC-B528-BB123868926D -setup Install -title {Copying Files} -component CopyFiles -type pane -active Yes -parent Standard
  15906. InstallComponent 5315266E-E68B-435E-AFBC-E218FDC19369 -setup Install -title {Disable Buttons} -component ModifyWidget -type action -active Yes -parent 354BBA54-2679-44CC-B528-BB123868926D
  15907. InstallComponent 1D8EB93F-5852-46CE-B93A-A4ED5672E32F -setup Install -title {Execute Action} -component ExecuteAction -type action -active Yes -parent 354BBA54-2679-44CC-B528-BB123868926D
  15908. InstallComponent A6185DCF-A645-44CE-BCA8-AD0CF2DD3183 -setup Install -title {Move Forward} -component MoveForward -type action -active Yes -parent 354BBA54-2679-44CC-B528-BB123868926D
  15909. InstallComponent 4C3FF654-9F5C-4679-B71D-F23E14F61844 -setup Install -title {Setup Complete} -component SetupComplete -type pane -active Yes -parent Standard
  15910. InstallComponent A41FE23D-88CA-44B9-B9A7-18C2F2879E8D -setup Install -conditions {D34364B6-8486-412D-914A-34A01B029D62 FB0A7015-A12E-4BF1-8044-9D46E9512987} -title {View Readme Checkbutton} -component AddWidget -command insert -type action -active Yes -parent 4C3FF654-9F5C-4679-B71D-F23E14F61844
  15911. Condition D34364B6-8486-412D-914A-34A01B029D62 -active Yes -parent A41FE23D-88CA-44B9-B9A7-18C2F2879E8D -title {File Exists Condition} -component FileExistsCondition
  15912. Condition FB0A7015-A12E-4BF1-8044-9D46E9512987 -active Yes -parent A41FE23D-88CA-44B9-B9A7-18C2F2879E8D -title {String Is Condition} -component StringIsCondition
  15913. InstallComponent 55DB7606-259D-4B3C-A3C1-5CCF6C12638C -setup Install -conditions {80E90A24-8A32-4E27-9C5C-3B5EF6283D1F 71ED690B-1531-4FC1-A869-F347967DE87B} -title {Launch Application Checkbutton} -component AddWidget -command insert -type action -active Yes -parent 4C3FF654-9F5C-4679-B71D-F23E14F61844
  15914. Condition 80E90A24-8A32-4E27-9C5C-3B5EF6283D1F -active Yes -parent 55DB7606-259D-4B3C-A3C1-5CCF6C12638C -title {File Exists Condition} -component FileExistsCondition
  15915. Condition 71ED690B-1531-4FC1-A869-F347967DE87B -active Yes -parent 55DB7606-259D-4B3C-A3C1-5CCF6C12638C -title {String Is Condition} -component StringIsCondition
  15916. InstallComponent 85CBEC09-95F0-4510-8130-23292CD4E280 -setup Install -conditions {50748934-8AC2-4A3C-AC85-D701FAC60C49 00751641-DBBA-47C1-A7B9-0975B0C2644F} -title {Desktop Shortcut Checkbutton} -component AddWidget -command insert -type action -active Yes -parent 4C3FF654-9F5C-4679-B71D-F23E14F61844
  15917. Condition 50748934-8AC2-4A3C-AC85-D701FAC60C49 -active Yes -parent 85CBEC09-95F0-4510-8130-23292CD4E280 -title {File Exists Condition} -component FileExistsCondition
  15918. Condition 00751641-DBBA-47C1-A7B9-0975B0C2644F -active Yes -parent 85CBEC09-95F0-4510-8130-23292CD4E280 -title {String Is Condition} -component StringIsCondition
  15919. InstallComponent D1224075-F20A-4015-A39F-9DCE7111AF5B -setup Install -conditions {426B6A63-5AB7-42BB-B78F-3236D745399B 4439AB66-CCD9-4421-BDB3-851F51B2DEE7 C66D6544-4FCE-4697-B0E4-4B6F3A462973} -title {Quick Launch Shortcut Checkbutton} -component AddWidget -command insert -type action -active Yes -parent 4C3FF654-9F5C-4679-B71D-F23E14F61844
  15920. Condition 426B6A63-5AB7-42BB-B78F-3236D745399B -active Yes -parent D1224075-F20A-4015-A39F-9DCE7111AF5B -title {Platform Condition} -component PlatformCondition
  15921. Condition 4439AB66-CCD9-4421-BDB3-851F51B2DEE7 -active Yes -parent D1224075-F20A-4015-A39F-9DCE7111AF5B -title {File Exists Condition} -component FileExistsCondition
  15922. Condition C66D6544-4FCE-4697-B0E4-4B6F3A462973 -active Yes -parent D1224075-F20A-4015-A39F-9DCE7111AF5B -title {String Is Condition} -component StringIsCondition
  15923. InstallType ::Default
  15924. InstallComponent 44F378EE-B695-45D5-96FE-1BBC93596B1F -setup Install -title {Copying Files} -component CopyFiles -type pane -active Yes -parent Default
  15925. InstallComponent 4C97A1FF-3B60-4E13-9D4E-020C32F5A661 -setup Install -title {Disable Buttons} -component ModifyWidget -type action -active Yes -parent 44F378EE-B695-45D5-96FE-1BBC93596B1F
  15926. InstallComponent CBF10125-0D47-4DBB-9630-0CA6FDA9489B -setup Install -title {Execute Action} -component ExecuteAction -type action -active Yes -parent 44F378EE-B695-45D5-96FE-1BBC93596B1F
  15927. InstallComponent EE3898B7-7F54-4743-87F2-FCBF21BBC5C8 -setup Install -title {Move Forward} -component MoveForward -type action -active Yes -parent 44F378EE-B695-45D5-96FE-1BBC93596B1F
  15928. InstallComponent A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3 -setup Install -title {Setup Complete} -component SetupComplete -type pane -active Yes -parent Default
  15929. InstallComponent 6A4B5CE4-BBF6-4444-8593-E188A69FA768 -setup Install -conditions {AB94C219-6C76-4908-9CCE-99A4E7AB484F 662CEDC2-7F2F-44F4-B260-A7990F8F4E4F} -title {View Readme Checkbutton} -component AddWidget -command insert -type action -active Yes -parent A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3
  15930. Condition AB94C219-6C76-4908-9CCE-99A4E7AB484F -active Yes -parent 6A4B5CE4-BBF6-4444-8593-E188A69FA768 -title {File Exists Condition} -component FileExistsCondition
  15931. Condition 662CEDC2-7F2F-44F4-B260-A7990F8F4E4F -active Yes -parent 6A4B5CE4-BBF6-4444-8593-E188A69FA768 -title {String Is Condition} -component StringIsCondition
  15932. InstallComponent 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4 -setup Install -conditions {77FEE21B-4F91-4C17-B6FF-FA8A07FEAE20 5F9F234B-8C55-46E5-B883-78843926A386} -title {Launch Application Checkbutton} -component AddWidget -command insert -type action -active Yes -parent A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3
  15933. Condition 77FEE21B-4F91-4C17-B6FF-FA8A07FEAE20 -active Yes -parent 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4 -title {File Exists Condition} -component FileExistsCondition
  15934. Condition 5F9F234B-8C55-46E5-B883-78843926A386 -active Yes -parent 4DA01EFD-7C97-4B70-8E91-A5FDC965F7F4 -title {String Is Condition} -component StringIsCondition
  15935. InstallComponent C91C5668-E984-4541-871C-CF6194F3F71F -setup Install -conditions {25542048-E343-4AD5-B1A3-90B504E68373 642021C6-FD45-486A-91AB-8A333627A3D9} -title {Desktop Shortcut Checkbutton} -component AddWidget -command insert -type action -active Yes -parent A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3
  15936. Condition 25542048-E343-4AD5-B1A3-90B504E68373 -active Yes -parent C91C5668-E984-4541-871C-CF6194F3F71F -title {File Exists Condition} -component FileExistsCondition
  15937. Condition 642021C6-FD45-486A-91AB-8A333627A3D9 -active Yes -parent C91C5668-E984-4541-871C-CF6194F3F71F -title {String Is Condition} -component StringIsCondition
  15938. InstallComponent D0A37977-56A8-4296-9659-512D495FF25E -setup Install -conditions {C33F8E7D-7970-43C4-B653-FFA8CE170EC8 78C0D25B-104F-4227-ADF5-C342079844AD 0ACE12C8-A333-46A4-B24F-7C895219F2B0} -title {Quick Launch Shortcut Checkbutton} -component AddWidget -command insert -type action -active Yes -parent A4C5425B-25E9-4BB8-AC0A-3808CF2F27B3
  15939. Condition C33F8E7D-7970-43C4-B653-FFA8CE170EC8 -active Yes -parent D0A37977-56A8-4296-9659-512D495FF25E -title {Platform Condition} -component PlatformCondition
  15940. Condition 78C0D25B-104F-4227-ADF5-C342079844AD -active Yes -parent D0A37977-56A8-4296-9659-512D495FF25E -title {File Exists Condition} -component FileExistsCondition
  15941. Condition 0ACE12C8-A333-46A4-B24F-7C895219F2B0 -active Yes -parent D0A37977-56A8-4296-9659-512D495FF25E -title {String Is Condition} -component StringIsCondition
  15942. InstallType ::Silent
  15943. InstallComponent 242E27AA-551C-4796-B099-DFCAF9498E62 -setup Install -title {Execute Action} -component ExecuteAction -type action -active Yes -parent Silent
  15944. InstallComponent E4876404-6179-4839-B6F0-0CE2C46F3AC0 -setup Install -title Exit -component Exit -type action -active Yes -parent Silent
  15945. InstallType ::ActionGroups
  15946. InstallComponent 41678FFA-A713-40E4-8E81-E374344D2971 -setup Install -title {Startup Actions} -type actiongroup -active Yes -parent ActionGroups
  15947. InstallComponent BA400D3F-D7F5-4B08-96DC-091A0416E08E -setup Install -title {Create Install Panes} -component CreateInstallPanes -type action -active Yes -parent 41678FFA-A713-40E4-8E81-E374344D2971
  15948. InstallComponent 62EF759C-DEDA-4D58-AED0-90D0974F1657 -setup Install -title {Install Actions} -type actiongroup -active Yes -parent ActionGroups
  15949. InstallComponent D9504B73-531B-4DAB-87F0-811824D98680 -setup Install -title {Install Selected Files} -component InstallSelectedFiles -type action -active Yes -parent 62EF759C-DEDA-4D58-AED0-90D0974F1657
  15950. InstallComponent 4F8BE818-346C-4637-AE4C-4A6B7C48CB74 -setup Install -title {Install Uninstaller} -component InstallUninstaller -type action -active Yes -parent 62EF759C-DEDA-4D58-AED0-90D0974F1657
  15951. InstallComponent 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70 -setup Install -conditions DCE54AB7-C9B6-4B3B-8FAC-C3D332B634CD -title {Windows Uninstall Registry} -component AddWindowsUninstallEntry -command insert -type action -active Yes -parent 62EF759C-DEDA-4D58-AED0-90D0974F1657
  15952. Condition DCE54AB7-C9B6-4B3B-8FAC-C3D332B634CD -active Yes -parent 4B3A54D3-1471-47A2-8AD9-9098BB8E1B70 -title {Platform Condition} -component PlatformCondition
  15953. InstallComponent A9D2ED78-502D-4FA8-A26A-C93DE0CAE4F3 -setup Install -conditions 9B3864C7-F41B-43F6-B5FB-86D60573F3EA -title {Program Shortcut} -component InstallWindowsShortcut -command insert -type action -active Yes -parent 62EF759C-DEDA-4D58-AED0-90D0974F1657
  15954. Condition 9B3864C7-F41B-43F6-B5FB-86D60573F3EA -active Yes -parent A9D2ED78-502D-4FA8-A26A-C93DE0CAE4F3 -title {Platform Condition} -component PlatformCondition
  15955. InstallComponent 4D90F974-8C14-4E2F-B458-82FE9510F546 -setup Install -conditions DC88586F-6788-4678-A90C-4D79A8DE9BE4 -title {Uninstall Shortcut} -component InstallWindowsShortcut -command insert -type action -active Yes -parent 62EF759C-DEDA-4D58-AED0-90D0974F1657
  15956. Condition DC88586F-6788-4678-A90C-4D79A8DE9BE4 -active Yes -parent 4D90F974-8C14-4E2F-B458-82FE9510F546 -title {Platform Condition} -component PlatformCondition
  15957. InstallComponent 5DD477BC-16FE-4DDC-9161-E30D7E1DB549 -setup Install -title {Finish Actions} -type actiongroup -active Yes -parent ActionGroups
  15958. InstallComponent 75C4743C-92B4-41B2-9162-2929B3A08869 -setup Install -conditions {B8D63777-F7F8-4C24-901D-8024A7AB2F06 625FF735-46E7-411C-ABFE-D0BE7677001B} -title {Install Desktop Shortcut} -component InstallDesktopShortcut -command insert -type action -active Yes -parent 5DD477BC-16FE-4DDC-9161-E30D7E1DB549
  15959. Condition B8D63777-F7F8-4C24-901D-8024A7AB2F06 -active Yes -parent 75C4743C-92B4-41B2-9162-2929B3A08869 -title {String Is Condition} -component StringIsCondition
  15960. Condition 625FF735-46E7-411C-ABFE-D0BE7677001B -active Yes -parent 75C4743C-92B4-41B2-9162-2929B3A08869 -title {File Exists Condition} -component FileExistsCondition
  15961. InstallComponent 1A5BA78D-0B6B-4051-B460-B94426C061F7 -setup Install -conditions {B8C49671-1167-476C-90AF-509528EAC2EE 3801681B-4E3B-4AA7-8787-A96E18DD14B6 211BD58E-6D44-49A5-AC4F-2DFA63C61083} -title {Install Quick Launch Shortcut} -component InstallWindowsShortcut -command insert -type action -active Yes -parent 5DD477BC-16FE-4DDC-9161-E30D7E1DB549
  15962. Condition B8C49671-1167-476C-90AF-509528EAC2EE -active Yes -parent 1A5BA78D-0B6B-4051-B460-B94426C061F7 -title {String Is Condition} -component StringIsCondition
  15963. Condition 3801681B-4E3B-4AA7-8787-A96E18DD14B6 -active Yes -parent 1A5BA78D-0B6B-4051-B460-B94426C061F7 -title {Platform Condition} -component PlatformCondition
  15964. Condition 211BD58E-6D44-49A5-AC4F-2DFA63C61083 -active Yes -parent 1A5BA78D-0B6B-4051-B460-B94426C061F7 -title {File Exists Condition} -component FileExistsCondition
  15965. InstallComponent 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8 -setup Install -conditions {BFF0AA9C-A6A8-490D-81E8-6BDF94581355 29E269AB-C3E3-4698-A8C4-0498DD1B541A F56B3A55-F558-4D2C-ADFF-8B8B2C02E40F} -title {View Readme Window} -component TextWindow -command insert -type action -active Yes -parent 5DD477BC-16FE-4DDC-9161-E30D7E1DB549
  15966. Condition BFF0AA9C-A6A8-490D-81E8-6BDF94581355 -active Yes -parent 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8 -title {String Is Condition} -component StringIsCondition
  15967. Condition 29E269AB-C3E3-4698-A8C4-0498DD1B541A -active Yes -parent 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8 -title {String Is Condition} -component StringIsCondition
  15968. Condition F56B3A55-F558-4D2C-ADFF-8B8B2C02E40F -active Yes -parent 789B80CD-AC41-4B69-9E7C-DF7C12C82AA8 -title {File Exists Condition} -component FileExistsCondition
  15969. InstallComponent A5A6DE1F-6058-4D53-ACB1-C0E411A485AE -setup Install -conditions {9D77E823-EBFA-474A-9016-D327212A026B 8E64750C-6A5E-4955-9FA0-396CC703201B 4F4A68D9-4A26-4E38-93FC-94F3EB6DCAE7} -title {Launch Application} -component ExecuteExternalProgram -command insert -type action -active Yes -parent 5DD477BC-16FE-4DDC-9161-E30D7E1DB549
  15970. Condition 9D77E823-EBFA-474A-9016-D327212A026B -active Yes -parent A5A6DE1F-6058-4D53-ACB1-C0E411A485AE -title {String Is Condition} -component StringIsCondition
  15971. Condition 8E64750C-6A5E-4955-9FA0-396CC703201B -active Yes -parent A5A6DE1F-6058-4D53-ACB1-C0E411A485AE -title {String Is Condition} -component StringIsCondition
  15972. Condition 4F4A68D9-4A26-4E38-93FC-94F3EB6DCAE7 -active Yes -parent A5A6DE1F-6058-4D53-ACB1-C0E411A485AE -title {File Exists Condition} -component FileExistsCondition
  15973. InstallComponent 1AF0EAD8-E770-4022-849F-D4C625BE1284 -setup Install -title {Cancel Actions} -type actiongroup -active Yes -parent ActionGroups
  15974.  
  15975.  
  15976. proc main {} {
  15977. ::InstallJammer::InstallMain
  15978. }
  15979.  
  15980. if {![info exists ::InstallJammer]} { main }
  15981.  
  15982.